1 // Copyright (c) 1999-2002 Microsoft Corporation. All rights reserved. 2 // 3 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 4 // WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 5 // WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 6 // THE ENTIRE RISK OF USE OR RESULTS IN CONNECTION WITH THE USE OF THIS CODE 7 // AND INFORMATION REMAINS WITH THE USER. 8 // 9 using System; 10 using System.ComponentModel; 11 using System.ComponentModel.Design; 12 using System.Collections; 13 using System.Collections.Generic; 14 using System.Resources; 15 using System.Reflection; 16 using System.Globalization; 17 using System.Security; 18 using System.Security.Permissions; 19 using System.Workflow.ComponentModel; 20 using System.Workflow.ComponentModel.Compiler; 21 using System.Workflow.ComponentModel.Design; 22 23 /********************************************************************* 24 * NOTE: A copy of this file exists at: WF\Common\Shared 25 * The two files must be kept in sync. Any change made here must also 26 * be made to WF\Common\Shared\BasePropertyDescriptor.cs 27 *********************************************************************/ 28 29 namespace System.Workflow.Activities.Common 30 { 31 #region Class PropertyDescriptorUtils 32 internal static class PropertyDescriptorUtils 33 { GetSite(IServiceProvider serviceProvider, object component)34 internal static ISite GetSite(IServiceProvider serviceProvider, object component) 35 { 36 ISite site = null; 37 38 if (component != null) 39 { 40 if ((component is IComponent) && ((IComponent)component).Site != null) 41 site = ((IComponent)component).Site; 42 43 if (site == null && component.GetType().IsArray && (component as object[]).Length > 0 && (component as object[])[0] is IComponent) 44 site = ((IComponent)(component as object[])[0]).Site; 45 46 if (site == null && serviceProvider != null) 47 { 48 IReferenceService referenceService = serviceProvider.GetService(typeof(IReferenceService)) as IReferenceService; 49 if (referenceService != null) 50 { 51 IComponent baseComponent = referenceService.GetComponent(component); 52 if (baseComponent != null) 53 site = baseComponent.Site; 54 } 55 } 56 } 57 58 if (site == null) 59 site = serviceProvider as ISite; 60 61 return site; 62 } 63 GetComponent(ITypeDescriptorContext context)64 internal static IComponent GetComponent(ITypeDescriptorContext context) 65 { 66 ISite site = (context != null) ? GetSite(context, context.Instance) : null; 67 return (site != null) ? site.Component : null; 68 } 69 GetBaseType(PropertyDescriptor property, object owner, IServiceProvider serviceProvider)70 internal static Type GetBaseType(PropertyDescriptor property, object owner, IServiceProvider serviceProvider) 71 { 72 Type baseType = null; 73 74 Type ownerType = owner.GetType(); 75 if (owner != null) 76 { 77 IDynamicPropertyTypeProvider basetypeProvider = owner as IDynamicPropertyTypeProvider; 78 if (basetypeProvider != null) 79 baseType = basetypeProvider.GetPropertyType(serviceProvider, property.Name); 80 } 81 82 if (baseType == null) 83 baseType = property.PropertyType; 84 85 return baseType; 86 } 87 SetPropertyValue(IServiceProvider serviceProvider, PropertyDescriptor propertyDescriptor, object component, object value)88 internal static void SetPropertyValue(IServiceProvider serviceProvider, PropertyDescriptor propertyDescriptor, object component, object value) 89 { 90 ComponentChangeDispatcher componentChange = new ComponentChangeDispatcher(serviceProvider, component, propertyDescriptor); 91 try 92 { 93 propertyDescriptor.SetValue(component, value); 94 } 95 catch (Exception t) 96 { 97 // If there was a problem setting the controls property then we get: 98 // ArgumentException (from properties set method) 99 // ==> Becomes inner exception of TargetInvocationException 100 // ==> caught here 101 // Propagate the original exception up 102 if (t is TargetInvocationException && t.InnerException != null) 103 throw t.InnerException; 104 else 105 throw t; 106 } 107 finally 108 { 109 componentChange.Dispose(); 110 } 111 } 112 } 113 #endregion 114 115 #region Class ComponentChangeDispatcher 116 internal sealed class ComponentChangeDispatcher : IDisposable 117 { 118 private IServiceProvider serviceProvider; 119 private object component; 120 private PropertyDescriptor property; 121 private object oldValue; 122 private object newValue; 123 ComponentChangeDispatcher(IServiceProvider serviceProvider, object component, PropertyDescriptor propertyDescriptor)124 public ComponentChangeDispatcher(IServiceProvider serviceProvider, object component, PropertyDescriptor propertyDescriptor) 125 { 126 this.serviceProvider = serviceProvider; 127 this.component = component; 128 this.property = propertyDescriptor; 129 130 IComponentChangeService changeService = serviceProvider.GetService(typeof(IComponentChangeService)) as IComponentChangeService; 131 if (changeService != null) 132 { 133 try 134 { 135 newValue = oldValue = propertyDescriptor.GetValue(component); 136 propertyDescriptor.AddValueChanged(component, new EventHandler(OnValueChanged)); 137 changeService.OnComponentChanging(component, propertyDescriptor); 138 } 139 catch (CheckoutException coEx) 140 { 141 if (coEx == CheckoutException.Canceled) 142 return; 143 throw coEx; 144 } 145 } 146 } 147 Dispose()148 public void Dispose() 149 { 150 IComponentChangeService changeService = this.serviceProvider.GetService(typeof(IComponentChangeService)) as IComponentChangeService; 151 if (changeService != null) 152 changeService.OnComponentChanged(this.component, this.property, this.oldValue, this.newValue); 153 } 154 OnValueChanged(object sender, EventArgs e)155 private void OnValueChanged(object sender, EventArgs e) 156 { 157 this.newValue = this.property.GetValue(this.component); 158 this.property.RemoveValueChanged(this.component, new EventHandler(OnValueChanged)); 159 } 160 } 161 #endregion 162 163 #region Class DynamicPropertyDescriptor 164 internal class DynamicPropertyDescriptor : PropertyDescriptor 165 { 166 private IServiceProvider serviceProvider; 167 private PropertyDescriptor realPropertyDescriptor; 168 DynamicPropertyDescriptor(IServiceProvider serviceProvider, PropertyDescriptor descriptor)169 public DynamicPropertyDescriptor(IServiceProvider serviceProvider, PropertyDescriptor descriptor) 170 : base(descriptor, null) 171 { 172 this.serviceProvider = serviceProvider; 173 this.realPropertyDescriptor = descriptor; 174 } 175 176 public IServiceProvider ServiceProvider 177 { 178 get 179 { 180 return this.serviceProvider; 181 } 182 } 183 184 public PropertyDescriptor RealPropertyDescriptor 185 { 186 get 187 { 188 return this.realPropertyDescriptor; 189 } 190 } 191 192 public override string Category 193 { 194 get 195 { 196 return this.realPropertyDescriptor.Category; 197 } 198 } 199 200 public override AttributeCollection Attributes 201 { 202 get 203 { 204 ArrayList attributes = new ArrayList(); 205 attributes.AddRange(this.realPropertyDescriptor.Attributes); 206 attributes.Add(new MergablePropertyAttribute(false)); 207 return new AttributeCollection((Attribute[])attributes.ToArray(typeof(Attribute))); 208 } 209 } 210 211 public override TypeConverter Converter 212 { 213 get 214 { 215 return this.realPropertyDescriptor.Converter; 216 } 217 } 218 219 public override string Description 220 { 221 get 222 { 223 return this.realPropertyDescriptor.Description; 224 } 225 } 226 227 public override string DisplayName 228 { 229 get 230 { 231 return this.realPropertyDescriptor.DisplayName; 232 } 233 } 234 235 public override Type ComponentType 236 { 237 get 238 { 239 return this.realPropertyDescriptor.ComponentType; 240 } 241 } 242 243 public override Type PropertyType 244 { 245 get 246 { 247 return this.realPropertyDescriptor.PropertyType; 248 } 249 } 250 251 public override bool IsReadOnly 252 { 253 get 254 { 255 return this.realPropertyDescriptor.IsReadOnly; 256 } 257 } 258 ResetValue(object component)259 public override void ResetValue(object component) 260 { 261 this.realPropertyDescriptor.ResetValue(component); 262 } 263 CanResetValue(object component)264 public override bool CanResetValue(object component) 265 { 266 return this.realPropertyDescriptor.CanResetValue(component); 267 } 268 ShouldSerializeValue(object component)269 public override bool ShouldSerializeValue(object component) 270 { 271 // work around: The real property descriptor is returning false for all the 272 // SequentialWorkflow class's properties because they all get replaced with 273 // InheritedPropertyDescriptors on Initialization (in the ComponentDesigner 274 // base class), which is causing problems in the code-only serialization. 275 if (string.Equals(this.realPropertyDescriptor.GetType().FullName, "System.ComponentModel.Design.InheritedPropertyDescriptor", StringComparison.Ordinal)) 276 return true; 277 278 return this.realPropertyDescriptor.ShouldSerializeValue(component); 279 } 280 GetValue(object component)281 public override object GetValue(object component) 282 { 283 // When a child property is of type event, component could be null. 284 if (component == null) 285 return null; 286 287 return this.realPropertyDescriptor.GetValue(component); 288 } 289 SetValue(object component, object value)290 public override void SetValue(object component, object value) 291 { 292 if (component is IComponent) 293 this.realPropertyDescriptor.SetValue(component, value); 294 else 295 PropertyDescriptorUtils.SetPropertyValue(ServiceProvider, this.realPropertyDescriptor, component, value); 296 } 297 } 298 #endregion 299 300 #region Class ParameterInfoBasedPropertyDescriptor 301 302 internal class ParameterInfoBasedPropertyDescriptor : PropertyDescriptor 303 { 304 private Type componentType; 305 private string desc = string.Empty; 306 private bool avoidDuplication = false; 307 private object parameter = null; // Could be either ParameterInfo or PropertyInfo 308 private Type parameterType = null; 309 private const string parameterPrefix = "(Parameter) "; 310 ParameterInfoBasedPropertyDescriptor(Type componentType, ParameterInfo paramInfo, bool avoidDuplication, params Attribute[] attributes)311 internal ParameterInfoBasedPropertyDescriptor(Type componentType, ParameterInfo paramInfo, bool avoidDuplication, params Attribute[] attributes) 312 : base((paramInfo.Position == -1) ? "(ReturnValue)" : paramInfo.Name, attributes) 313 { 314 if (componentType == null) 315 throw new ArgumentNullException("componentType"); 316 317 if (paramInfo == null) 318 throw new ArgumentNullException("paramInfo"); 319 320 if (paramInfo.ParameterType == null) 321 throw new InvalidOperationException(SR.GetString(SR.Error_ParameterTypeResolution, paramInfo.Name)); 322 323 this.componentType = componentType; 324 this.parameter = paramInfo; 325 this.avoidDuplication = avoidDuplication; 326 this.parameterType = paramInfo.ParameterType; 327 328 //Build and cache description 329 string qualifier = String.Empty; 330 if ((paramInfo.ParameterType != null) && (paramInfo.ParameterType.IsByRef || (paramInfo.IsIn && paramInfo.IsOut))) 331 qualifier = SR.GetString(SR.Ref); 332 else if (paramInfo.IsOut || paramInfo.Name == null) 333 qualifier = SR.GetString(SR.Out); 334 else 335 qualifier = SR.GetString(SR.In); 336 this.desc = SR.GetString(SR.ParameterDescription, paramInfo.ParameterType.FullName); 337 } 338 339 ParameterInfoBasedPropertyDescriptor(Type componentType, string propertyName, Type propertyType, bool avoidDuplication, params Attribute[] attributes)340 internal ParameterInfoBasedPropertyDescriptor(Type componentType, string propertyName, Type propertyType, bool avoidDuplication, params Attribute[] attributes) 341 : base(propertyName, attributes) 342 { 343 if (componentType == null) 344 throw new ArgumentNullException("componentType"); 345 346 if (propertyType == null) 347 throw new InvalidOperationException(SR.GetString(SR.Error_ParameterTypeResolution, propertyName)); 348 349 this.componentType = componentType; 350 this.parameterType = propertyType; 351 this.avoidDuplication = avoidDuplication; 352 this.desc = SR.GetString(SR.InvokeParameterDescription, propertyType.FullName.ToString()); 353 } 354 355 internal Type ParameterType 356 { 357 get 358 { 359 Type type = this.parameterType; 360 if (type.IsByRef) 361 type = type.GetElementType(); 362 return type; 363 } 364 } 365 366 public override string Description 367 { 368 get 369 { 370 return this.desc; 371 } 372 } 373 374 public override string Category 375 { 376 get 377 { 378 return SR.GetString(SR.Parameters); 379 } 380 } 381 GetEditor(Type editorBaseType)382 public override object GetEditor(Type editorBaseType) 383 { 384 return TypeDescriptor.GetEditor(PropertyType, editorBaseType); 385 } 386 387 public override string DisplayName 388 { 389 get 390 { 391 return this.Name; 392 } 393 } 394 395 public override bool IsReadOnly 396 { 397 get 398 { 399 return false; 400 } 401 } 402 403 public override Type ComponentType 404 { 405 get 406 { 407 return this.componentType; 408 } 409 } 410 411 public override string Name 412 { 413 get 414 { 415 if (this.avoidDuplication) 416 { 417 // WinOE Bug 10442: should only prefix with "(Parameter)" if there is and existing 418 // member of the same name. 419 return GetParameterPropertyName(this.componentType, base.Name); 420 } 421 else 422 return base.Name; 423 } 424 } 425 FindMatchingMember(string name, Type ownerType, bool ignoreCase)426 internal static MemberInfo FindMatchingMember(string name, Type ownerType, bool ignoreCase) 427 { 428 MemberInfo matchingMember = null; 429 foreach (MemberInfo memberInfo in ownerType.GetMembers(BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)) 430 { 431 if (memberInfo.Name.Equals(name, ((ignoreCase) ? StringComparison.CurrentCultureIgnoreCase : StringComparison.CurrentCulture))) 432 { 433 matchingMember = memberInfo; 434 break; 435 } 436 } 437 return matchingMember; 438 } 439 440 public override Type PropertyType 441 { 442 get 443 { 444 Type propertyType = ParameterType; 445 if (propertyType == null) 446 propertyType = typeof(ActivityBind); 447 return propertyType; 448 } 449 } 450 451 public override TypeConverter Converter 452 { 453 get 454 { 455 //We return this to make sure that we can bind parameters through UI 456 return new ActivityBindTypeConverter(); 457 } 458 } 459 460 public override AttributeCollection Attributes 461 { 462 get 463 { 464 ArrayList attributes = new ArrayList(); 465 attributes.AddRange(base.Attributes); 466 attributes.AddRange(TypeDescriptor.GetAttributes(PropertyType)); 467 return new AttributeCollection((Attribute[])attributes.ToArray(typeof(Attribute))); 468 } 469 } 470 ResetValue(object component)471 public override void ResetValue(object component) 472 { 473 if (PropertyType != null && !PropertyType.IsValueType) 474 SetValue(component, null); 475 } 476 CanResetValue(object component)477 public override bool CanResetValue(object component) 478 { 479 return false; 480 } 481 ShouldSerializeValue(object component)482 public override bool ShouldSerializeValue(object component) 483 { 484 return false; 485 } 486 SetValue(object component, object value)487 public override void SetValue(object component, object value) 488 { 489 // the logic for notifications is borrowed from ReflectPropertyDescritpor 490 if (component == null) 491 return; 492 493 IServiceProvider serviceProvider = GetSite(component); 494 ComponentChangeDispatcher componentChange = (serviceProvider != null) ? new ComponentChangeDispatcher(serviceProvider, component, this) : null; 495 496 try 497 { 498 WorkflowParameterBindingCollection parameters = GetParameterBindings(component); 499 if (parameters != null) 500 { 501 string propertyName = String.Empty; 502 if (this.Name.StartsWith(parameterPrefix, StringComparison.Ordinal)) 503 propertyName = this.Name.Substring(parameterPrefix.Length); 504 else 505 propertyName = this.Name; 506 507 WorkflowParameterBinding binding = null; 508 if (parameters.Contains(propertyName)) 509 binding = parameters[propertyName]; 510 else 511 { 512 binding = new WorkflowParameterBinding(propertyName); 513 parameters.Add(binding); 514 } 515 516 if (value is ActivityBind) 517 binding.SetBinding(WorkflowParameterBinding.ValueProperty, value as ActivityBind); 518 else 519 binding.SetValue(WorkflowParameterBinding.ValueProperty, value); 520 521 OnValueChanged(component, EventArgs.Empty); 522 } 523 } 524 catch (Exception t) 525 { 526 // If there was a problem setting the controls property then we get: 527 // ArgumentException (from properties set method) 528 // ==> Becomes inner exception of TargetInvocationException 529 // ==> caught here 530 // Propagate the original exception up 531 if (t is TargetInvocationException && t.InnerException != null) 532 throw t.InnerException; 533 else 534 throw t; 535 } 536 finally 537 { 538 // Now notify the change service that the change was successful. 539 if (componentChange != null) 540 componentChange.Dispose(); 541 } 542 } 543 GetValue(object component)544 public override object GetValue(object component) 545 { 546 WorkflowParameterBindingCollection parameters = GetParameterBindings(component); 547 string displayName = this.Name; 548 string propertyName = (displayName.StartsWith(parameterPrefix, StringComparison.Ordinal)) ? displayName.Substring(parameterPrefix.Length) : displayName; 549 if (parameters != null && parameters.Contains(propertyName)) 550 { 551 if (parameters[propertyName].IsBindingSet(WorkflowParameterBinding.ValueProperty)) 552 return parameters[propertyName].GetBinding(WorkflowParameterBinding.ValueProperty); 553 else 554 return parameters[propertyName].GetValue(WorkflowParameterBinding.ValueProperty); 555 } 556 557 return null; 558 } 559 GetParameterBindings(object component)560 private WorkflowParameterBindingCollection GetParameterBindings(object component) 561 { 562 WorkflowParameterBindingCollection retVal = null; 563 MemberInfo memberInfo = component.GetType().GetProperty("ParameterBindings", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.ExactBinding, null, typeof(WorkflowParameterBindingCollection), new Type[] { }, new ParameterModifier[] { }); 564 if (memberInfo != null) 565 retVal = component.GetType().InvokeMember("ParameterBindings", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.ExactBinding, null, component, new object[] { }, CultureInfo.InvariantCulture) as WorkflowParameterBindingCollection; 566 return retVal; 567 } 568 GetParameterPropertyName(Type componentType, string paramName)569 public static string GetParameterPropertyName(Type componentType, string paramName) 570 { 571 string paramPropertyName = paramName; 572 if (FindMatchingMember(paramName, componentType, false) != null) 573 paramPropertyName = parameterPrefix + paramName; 574 575 return paramPropertyName; 576 } 577 } 578 #endregion 579 580 #region IPropertyValueProvider Interface 581 internal interface IPropertyValueProvider 582 { GetPropertyValues(ITypeDescriptorContext typeDescriptorContext)583 ICollection GetPropertyValues(ITypeDescriptorContext typeDescriptorContext); 584 } 585 #endregion 586 587 #region Class PropertyValueProviderTypeConverter 588 internal class PropertyValueProviderTypeConverter : TypeConverter 589 { PropertyValueProviderTypeConverter()590 public PropertyValueProviderTypeConverter() 591 { 592 } 593 GetStandardValues(ITypeDescriptorContext context)594 public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) 595 { 596 // grab all property values 597 IPropertyValueProvider valuesProvider = null; 598 object[] instances = context.Instance as object[]; 599 if (instances != null && instances.Length > 0) 600 valuesProvider = instances[0] as IPropertyValueProvider; 601 else 602 valuesProvider = context.Instance as IPropertyValueProvider; 603 604 ICollection values = new object[] { }; 605 if (valuesProvider != null) 606 values = valuesProvider.GetPropertyValues(context); 607 608 return new StandardValuesCollection(values); 609 } 610 GetStandardValuesSupported(ITypeDescriptorContext context)611 public override bool GetStandardValuesSupported(ITypeDescriptorContext context) 612 { 613 return true; 614 } 615 GetStandardValuesExclusive(ITypeDescriptorContext context)616 public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) 617 { 618 return true; 619 } 620 } 621 #endregion 622 623 #region Class TypePropertyDescriptor 624 internal class TypePropertyDescriptor : DynamicPropertyDescriptor 625 { TypePropertyDescriptor(IServiceProvider serviceProvider, PropertyDescriptor actualPropDesc)626 public TypePropertyDescriptor(IServiceProvider serviceProvider, PropertyDescriptor actualPropDesc) 627 : base(serviceProvider, actualPropDesc) 628 { 629 } 630 631 public override TypeConverter Converter 632 { 633 get 634 { 635 // work around: a direct type comparison would not work because the types in this file are compiled 636 // into the component model and the activities dll separately. The assembly name differs thus 637 // the comparison fails. Work around by getting the type from the same assembly before doing 638 // the comparison. 639 TypeConverter baseTypeConverter = base.Converter; 640 string baseConverterTypeName = baseTypeConverter.GetType().FullName; 641 Type baseConverterType = Assembly.GetExecutingAssembly().GetType(baseConverterTypeName); 642 if (baseConverterType != null && typeof(TypePropertyTypeConverter).IsAssignableFrom(baseConverterType)) 643 return baseTypeConverter; 644 else 645 return new TypePropertyTypeConverter(); 646 } 647 } 648 GetValue(object component)649 public override object GetValue(object component) 650 { 651 if (component == null) 652 throw new ArgumentNullException("component"); 653 654 object value = base.GetValue(component); 655 656 if (value == null) 657 { 658 // See if there is a value in the user data DesignTimeTypeNames hashtable. 659 // If yes, it's probably a wrong type name. Show the name anyway. 660 DependencyObject dependencyObject = component as DependencyObject; 661 if (dependencyObject != null) 662 { 663 object key = DependencyProperty.FromName(this.RealPropertyDescriptor.Name, this.RealPropertyDescriptor.ComponentType); 664 value = Helpers.GetDesignTimeTypeName(dependencyObject, key); 665 if (string.IsNullOrEmpty(value as string)) 666 { 667 key = this.RealPropertyDescriptor.ComponentType.FullName + "." + this.RealPropertyDescriptor.Name; 668 value = Helpers.GetDesignTimeTypeName(dependencyObject, key); 669 } 670 } 671 } 672 673 return value; 674 } 675 SetValue(object component, object value)676 public override void SetValue(object component, object value) 677 { 678 if (component == null) 679 throw new ArgumentNullException("component"); 680 681 if (value != null) 682 { 683 Type type = value as Type; 684 ITypeFilterProvider filterProvider = PropertyDescriptorUtils.GetComponent(new TypeDescriptorContext(ServiceProvider, RealPropertyDescriptor, component)) as ITypeFilterProvider; 685 if (filterProvider != null) 686 filterProvider.CanFilterType(type, true); //this will throw an exception if the type is not correctly filterable 687 } 688 689 base.SetValue(component, value); 690 } 691 } 692 #endregion 693 694 #region Class TypePropertyValueProviderTypeConverter 695 internal class TypePropertyValueProviderTypeConverter : TypePropertyTypeConverter 696 { 697 // NOTE: Copied from PropertyValueProviderTypeConverter. 698 // The purpose of this type converter is so that we can both provide standard values and 699 // convert System.Type to string. GetStandardValues(ITypeDescriptorContext context)700 public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) 701 { 702 // grab all property values 703 IPropertyValueProvider valuesProvider = null; 704 object[] instances = context.Instance as object[]; 705 if (instances != null && instances.Length > 0) 706 valuesProvider = instances[0] as IPropertyValueProvider; 707 else 708 valuesProvider = context.Instance as IPropertyValueProvider; 709 710 ICollection values = new object[] { }; 711 if (valuesProvider != null && context != null) 712 values = valuesProvider.GetPropertyValues(context); 713 714 return new StandardValuesCollection(values); 715 } GetStandardValuesSupported(ITypeDescriptorContext context)716 public override bool GetStandardValuesSupported(ITypeDescriptorContext context) 717 { 718 return true; 719 } GetStandardValuesExclusive(ITypeDescriptorContext context)720 public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) 721 { 722 return true; 723 } 724 } 725 #endregion 726 727 #region Class TypePropertyTypeConverter 728 internal class TypePropertyTypeConverter : TypeConverter 729 { CanConvertFrom(ITypeDescriptorContext context, Type sourceType)730 public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 731 { 732 if (sourceType == null) 733 throw new ArgumentNullException("sourceType"); 734 735 if (TypeDescriptor.Equals(sourceType, typeof(string))) 736 return true; 737 738 return base.CanConvertFrom(context, sourceType); 739 740 } 741 CanConvertTo(ITypeDescriptorContext context, Type destinationType)742 public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) 743 { 744 if (destinationType == null) 745 throw new ArgumentNullException("destinationType"); 746 747 if (TypeDescriptor.Equals(destinationType, typeof(Type))) 748 return true; 749 750 return base.CanConvertTo(context, destinationType); 751 } 752 ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object valueToConvert)753 public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object valueToConvert) 754 { 755 string typeName = valueToConvert as string; 756 if (String.IsNullOrEmpty(typeName)) 757 return null; 758 759 if (context != null) 760 { 761 ITypeProvider typeProvider = context.GetService(typeof(ITypeProvider)) as ITypeProvider; 762 if (typeProvider != null) 763 return typeProvider.GetType(typeName, true); 764 } 765 766 return base.ConvertFrom(context, culture, valueToConvert); 767 } 768 ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)769 public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 770 { 771 if (value is Type && TypeDescriptor.Equals(destinationType, typeof(string))) 772 return ((Type)value).FullName; 773 774 return base.ConvertTo(context, culture, value, destinationType); 775 } 776 } 777 #endregion 778 } 779