The Labs \ Source Viewer \ SSCLI \ System.ComponentModel \ DebugExtendedPropertyDescriptor

  1. //------------------------------------------------------------------------------
  2. // <copyright file="DebugExtendedPropertyDescriptor.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. #if DEBUG
  16. /*
  17.    
  18.     This class exists in debug only.  It is a complete copy of the
  19.     V1.0 TypeDescriptor object and is used to validate that the
  20.     behavior of the V2.0 TypeDescriptor matches 1.0 behavior.
  21.    
  22. */
  23. namespace System.ComponentModel
  24. {
  25.    
  26.    
  27.     using System.Diagnostics;
  28.    
  29.     using System;
  30.     using System.ComponentModel.Design;
  31.     using System.Collections;
  32.     using Microsoft.Win32;
  33.     using System.Security.Permissions;
  34.    
  35.     /// <internalonly/>
  36.     /// <devdoc>
  37.     /// <para>
  38.     /// This class wraps an PropertyDescriptor with something that looks like a property. It
  39.     /// allows you to treat extended properties the same as regular properties.
  40.     /// </para>
  41.     /// </devdoc>
  42.     [HostProtection(SharedState = true)]
  43.     internal sealed class DebugExtendedPropertyDescriptor : PropertyDescriptor
  44.     {
  45.        
  46.         private readonly DebugReflectPropertyDescriptor extenderInfo;
  47.         // the extender property
  48.         private readonly IExtenderProvider provider;
  49.         // the guy providing it
  50.         private TypeConverter converter;
  51.         private object[] editors;
  52.         private Type[] editorTypes;
  53.         private int editorCount;
  54.        
  55.         /// <devdoc>
  56.         /// Creates a new extended property info. Callers can then treat this as
  57.         /// a standard property.
  58.         /// </devdoc>
  59.         public DebugExtendedPropertyDescriptor(DebugReflectPropertyDescriptor extenderInfo, Type receiverType, IExtenderProvider provider) : this(extenderInfo, receiverType, provider, null)
  60.         {
  61.         }
  62.        
  63.         /// <devdoc>
  64.         /// Creates a new extended property info. Callers can then treat this as
  65.         /// a standard property.
  66.         /// </devdoc>
  67.         public DebugExtendedPropertyDescriptor(DebugReflectPropertyDescriptor extenderInfo, Type receiverType, IExtenderProvider provider, Attribute[] attributes) : base(extenderInfo, attributes)
  68.         {
  69.            
  70.             Debug.Assert(extenderInfo != null, "DebugExtendedPropertyDescriptor must have extenderInfo");
  71.             Debug.Assert(provider != null, "DebugExtendedPropertyDescriptor must have provider");
  72.            
  73.             ArrayList attrList = new ArrayList(AttributeArray);
  74.             attrList.Add(ExtenderProvidedPropertyAttribute.Create(extenderInfo, receiverType, provider));
  75.             if (extenderInfo.IsReadOnly) {
  76.                 attrList.Add(ReadOnlyAttribute.Yes);
  77.             }
  78.            
  79.             Attribute[] temp = new Attribute[attrList.Count];
  80.             attrList.CopyTo(temp, 0);
  81.             AttributeArray = temp;
  82.            
  83.             this.extenderInfo = extenderInfo;
  84.             this.provider = provider;
  85.         }
  86.        
  87.         public DebugExtendedPropertyDescriptor(PropertyDescriptor extender, Attribute[] attributes) : base(extender, attributes)
  88.         {
  89.             Debug.Assert(extender != null, "The original PropertyDescriptor must be non-null");
  90.            
  91.             ExtenderProvidedPropertyAttribute attr = extender.Attributes[typeof(ExtenderProvidedPropertyAttribute)] as ExtenderProvidedPropertyAttribute;
  92.            
  93.             Debug.Assert(attr != null, "The original PropertyDescriptor does not have an ExtenderProvidedPropertyAttribute");
  94.            
  95.            
  96.             DebugReflectPropertyDescriptor reflectDesc = attr.ExtenderProperty as DebugReflectPropertyDescriptor;
  97.            
  98.             Debug.Assert(reflectDesc != null, "The original PropertyDescriptor has an invalid ExtenderProperty");
  99.            
  100.             this.extenderInfo = reflectDesc;
  101.             this.provider = attr.Provider;
  102.         }
  103.        
  104.         /// <devdoc>
  105.         /// Determines if the the component will allow its value to be reset.
  106.         /// </devdoc>
  107.         public override bool CanResetValue(object comp)
  108.         {
  109.             return extenderInfo.ExtenderCanResetValue(provider, comp);
  110.         }
  111.        
  112.         /// <devdoc>
  113.         /// Retrieves the type of the component this PropertyDescriptor is bound to.
  114.         /// </devdoc>
  115.         public override Type ComponentType {
  116.             get { return extenderInfo.ComponentType; }
  117.         }
  118.        
  119.         public override TypeConverter Converter {
  120.             get {
  121.                 if (converter == null) {
  122.                     TypeConverterAttribute attr = (TypeConverterAttribute)Attributes[typeof(TypeConverterAttribute)];
  123.                     if (attr.ConverterTypeName != null && attr.ConverterTypeName.Length > 0) {
  124.                         Type converterType = GetTypeFromName(attr.ConverterTypeName);
  125.                         if (converterType != null && typeof(TypeConverter).IsAssignableFrom(converterType)) {
  126.                             converter = (TypeConverter)CreateInstance(converterType);
  127.                         }
  128.                     }
  129.                    
  130.                     if (converter == null) {
  131.                         converter = DebugTypeDescriptor.GetConverter(PropertyType);
  132.                     }
  133.                 }
  134.                 return converter;
  135.             }
  136.         }
  137.        
  138.         /// <devdoc>
  139.         /// Determines if the property can be written to.
  140.         /// </devdoc>
  141.         public override bool IsReadOnly {
  142.             get { return Attributes[typeof(ReadOnlyAttribute)].Equals(ReadOnlyAttribute.Yes); }
  143.         }
  144.        
  145.         /// <devdoc>
  146.         /// Retrieves the data type of the property.
  147.         /// </devdoc>
  148.         public override Type PropertyType {
  149.             get { return extenderInfo.ExtenderGetType(provider); }
  150.         }
  151.        
  152.         /// <devdoc>
  153.         /// Retrieves the display name of the property. This is the name that will
  154.         /// be displayed in a properties window. This will be the same as the property
  155.         /// name for most properties.
  156.         /// </devdoc>
  157.         public override string DisplayName {
  158.             get {
  159.                 string name = Name;
  160.                 ISite site = GetSite(provider);
  161.                 if (site != null) {
  162.                     string providerName = site.Name;
  163.                     if (providerName != null && providerName.Length > 0) {
  164.                         name = SR.GetString(SR.MetaExtenderName, name, providerName);
  165.                     }
  166.                 }
  167.                 return name;
  168.             }
  169.         }
  170.        
  171.         /// <devdoc>
  172.         /// Retrieves the properties
  173.         /// </devdoc>
  174.         public override PropertyDescriptorCollection GetChildProperties(object instance, Attribute[] filter)
  175.         {
  176.             if (instance == null) {
  177.                 return DebugTypeDescriptor.GetProperties(PropertyType, filter);
  178.             }
  179.             else {
  180.                 return DebugTypeDescriptor.GetProperties(instance, filter);
  181.             }
  182.         }
  183.        
  184.         /// <devdoc>
  185.         /// <para>
  186.         /// Gets an editor of the specified type.
  187.         /// </para>
  188.         /// </devdoc>
  189.         public override object GetEditor(Type editorBaseType)
  190.         {
  191.             object editor = null;
  192.            
  193.             // Check the editors we've already created for this type.
  194.             //
  195.             if (editorTypes != null) {
  196.                 for (int i = 0; i < editorCount; i++) {
  197.                     if (editorTypes[i] == editorBaseType) {
  198.                         return editors[i];
  199.                     }
  200.                 }
  201.             }
  202.            
  203.             // If one wasn't found, then we must go through the attributes.
  204.             //
  205.             if (editor == null) {
  206.                 for (int i = 0; i < Attributes.Count; i++) {
  207.                    
  208.                     if (!(Attributes[i] is EditorAttribute)) {
  209.                         continue;
  210.                     }
  211.                    
  212.                     EditorAttribute attr = (EditorAttribute)Attributes[i];
  213.                     Type editorType = GetTypeFromName(attr.EditorBaseTypeName);
  214.                    
  215.                     if (editorBaseType == editorType) {
  216.                         Type type = GetTypeFromName(attr.EditorTypeName);
  217.                         if (type != null) {
  218.                             editor = CreateInstance(type);
  219.                             break;
  220.                         }
  221.                     }
  222.                 }
  223.                
  224.                 // Now, if we failed to find it in our own attributes, go to the
  225.                 // component descriptor.
  226.                 //
  227.                 if (editor == null) {
  228.                     editor = DebugTypeDescriptor.GetEditor(PropertyType, editorBaseType);
  229.                 }
  230.                
  231.                 // Now, another slot in our editor cache for next time
  232.                 //
  233.                 if (editorTypes == null) {
  234.                     editorTypes = new Type[5];
  235.                     editors = new object[5];
  236.                 }
  237.                
  238.                 if (editorCount >= editorTypes.Length) {
  239.                     Type[] newTypes = new Type[editorTypes.Length * 2];
  240.                     object[] newEditors = new object[editors.Length * 2];
  241.                     Array.Copy(editorTypes, newTypes, editorTypes.Length);
  242.                     Array.Copy(editors, newEditors, editors.Length);
  243.                     editorTypes = newTypes;
  244.                     editors = newEditors;
  245.                 }
  246.                
  247.                 editorTypes[editorCount] = editorBaseType;
  248.                 editors[editorCount++] = editor;
  249.             }
  250.            
  251.             return editor;
  252.         }
  253.        
  254.         /// <devdoc>
  255.         /// Retrieves the value of the property for the given component. This will
  256.         /// throw an exception if the component does not have this property.
  257.         /// </devdoc>
  258.         public override object GetValue(object comp)
  259.         {
  260.             return extenderInfo.ExtenderGetValue(provider, comp);
  261.         }
  262.        
  263.         /// <devdoc>
  264.         /// Resets the value of this property on comp to the default value.
  265.         /// </devdoc>
  266.         public override void ResetValue(object comp)
  267.         {
  268.             extenderInfo.ExtenderResetValue(provider, comp, this);
  269.         }
  270.        
  271.         /// <devdoc>
  272.         /// Sets the value of this property on the given component.
  273.         /// </devdoc>
  274.         public override void SetValue(object component, object value)
  275.         {
  276.             extenderInfo.ExtenderSetValue(provider, component, value, this);
  277.         }
  278.        
  279.         /// <devdoc>
  280.         /// Determines if this property should be persisted. A property is
  281.         /// to be persisted if it is marked as persistable through a
  282.         /// PersistableAttribute, and if the property contains something other
  283.         /// than the default value. Note, however, that this method will
  284.         /// return true for design time properties as well, so callers
  285.         /// should also check to see if a property is design time only before
  286.         /// persisting to runtime storage.
  287.         /// </devdoc>
  288.         public override bool ShouldSerializeValue(object comp)
  289.         {
  290.             return extenderInfo.ExtenderShouldSerializeValue(provider, comp);
  291.         }
  292.     }
  293. }
  294. #endif

Developer Fusion