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

  1. //------------------------------------------------------------------------------
  2. // <copyright file="PropertyDescriptorCollection.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. using System.Diagnostics.CodeAnalysis;
  16. [assembly: SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IDictionary.Add(System.Object,System.Object):System.Void")]
  17. [assembly: SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IList.set_Item(System.Int32,System.Object):System.Void")]
  18. [assembly: SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IDictionary.set_Item(System.Object,System.Object):System.Void")]
  19. /*
  20. This class has the HostProtectionAttribute. The purpose of this attribute is to enforce host-specific programming model guidelines, not security behavior.
  21. Suppress FxCop message - BUT REVISIT IF ADDING NEW SECURITY ATTRIBUTES.
  22. */
  23. [assembly: SuppressMessage("Microsoft.Security", "CA2112:SecuredTypesShouldNotExposeFields", Scope = "type", Target = "System.ComponentModel.PropertyDescriptorCollection")]
  24. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IDictionary.get_IsFixedSize():System.Boolean")]
  25. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IEnumerable.GetEnumerator():System.Collections.IEnumerator")]
  26. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IList.get_IsFixedSize():System.Boolean")]
  27. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.ICollection.get_SyncRoot():System.Object")]
  28. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IDictionary.Remove(System.Object):System.Void")]
  29. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.ICollection.get_IsSynchronized():System.Boolean")]
  30. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IDictionary.get_IsReadOnly():System.Boolean")]
  31. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IDictionary.get_Keys():System.Collections.ICollection")]
  32. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IList.get_IsReadOnly():System.Boolean")]
  33. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IList.Clear():System.Void")]
  34. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IList.IndexOf(System.Object):System.Int32")]
  35. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IDictionary.Contains(System.Object):System.Boolean")]
  36. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IList.RemoveAt(System.Int32):System.Void")]
  37. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.GetEnumerator():System.Collections.IEnumerator")]
  38. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IDictionary.Add(System.Object,System.Object):System.Void")]
  39. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IDictionary.Clear():System.Void")]
  40. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IDictionary.get_Values():System.Collections.ICollection")]
  41. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IList.Contains(System.Object):System.Boolean")]
  42. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IDictionary.GetEnumerator():System.Collections.IDictionaryEnumerator")]
  43. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IList.Remove(System.Object):System.Void")]
  44. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IList.get_Item(System.Int32):System.Object")]
  45. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IList.set_Item(System.Int32,System.Object):System.Void")]
  46. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IList.Add(System.Object):System.Int32")]
  47. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.CopyTo(System.Array,System.Int32):System.Void")]
  48. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IDictionary.get_Item(System.Object):System.Object")]
  49. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IDictionary.set_Item(System.Object,System.Object):System.Void")]
  50. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.IList.Insert(System.Int32,System.Object):System.Void")]
  51. [assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.System.Collections.ICollection.get_Count():System.Int32")]
  52. [assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection..ctor(System.ComponentModel.PropertyDescriptor[])")]
  53. [assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.get_Count():System.Int32")]
  54. [assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.get_Item(System.String):System.ComponentModel.PropertyDescriptor")]
  55. [assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection..ctor(System.ComponentModel.PropertyDescriptor[],System.Boolean)")]
  56. [assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.GetEnumerator():System.Collections.IEnumerator")]
  57. [assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.Find(System.String,System.Boolean):System.ComponentModel.PropertyDescriptor")]
  58. [assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "System.ComponentModel.PropertyDescriptorCollection.Sort(System.String[]):System.ComponentModel.PropertyDescriptorCollection")]
  59. namespace System.ComponentModel
  60. {
  61.     using Microsoft.Win32;
  62.     using System.Collections;
  63.     using System.Collections.Specialized;
  64.     using System.Diagnostics;
  65.     using System.Globalization;
  66.     using System.Runtime.InteropServices;
  67.     using System.Security.Permissions;
  68.    
  69.     /// <devdoc>
  70.     /// <para>
  71.     /// Represents a collection of properties.
  72.     /// </para>
  73.     /// </devdoc>
  74.     [System.Security.Permissions.HostProtection(Synchronization = true)]
  75.     public class PropertyDescriptorCollection : ICollection, IList, IDictionary
  76.     {
  77.        
  78.        
  79.         /// <devdoc>
  80.         /// An empty PropertyDescriptorCollection that can used instead of creating a new one with no items.
  81.         /// </devdoc>
  82.         [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2112:SecuredTypesShouldNotExposeFields")]
  83.         // ReadOnly fields - already shipped.
  84.         public static readonly PropertyDescriptorCollection Empty = new PropertyDescriptorCollection(null, true);
  85.        
  86.         private IDictionary cachedFoundProperties;
  87.         private bool cachedIgnoreCase;
  88.         private PropertyDescriptor[] properties;
  89.         private int propCount = 0;
  90.         private string[] namedSort;
  91.         private IComparer comparer;
  92.         private bool propsOwned = true;
  93.         private bool needSort = false;
  94.         private bool readOnly = false;
  95.        
  96.         /// <devdoc>
  97.         /// <para>
  98.         /// Initializes a new instance of the <see cref='System.ComponentModel.PropertyDescriptorCollection'/>
  99.         /// class.
  100.         /// </para>
  101.         /// </devdoc>
  102.         public PropertyDescriptorCollection(PropertyDescriptor[] properties)
  103.         {
  104.             this.properties = properties;
  105.             if (properties == null) {
  106.                 this.properties = new PropertyDescriptor[0];
  107.                 this.propCount = 0;
  108.             }
  109.             else {
  110.                 this.propCount = properties.Length;
  111.             }
  112.             this.propsOwned = true;
  113.         }
  114.        
  115.         /// <devdoc>
  116.         /// Initializes a new instance of a property descriptor collection, and allows you to mark the
  117.         /// collection as read-only so it cannot be modified.
  118.         /// </devdoc>
  119.         public PropertyDescriptorCollection(PropertyDescriptor[] properties, bool readOnly) : this(properties)
  120.         {
  121.             this.readOnly = readOnly;
  122.         }
  123.        
  124.         private PropertyDescriptorCollection(PropertyDescriptor[] properties, int propCount, string[] namedSort, IComparer comparer)
  125.         {
  126.             this.propsOwned = false;
  127.             if (namedSort != null) {
  128.                 this.namedSort = (string[])namedSort.Clone();
  129.             }
  130.             this.comparer = comparer;
  131.             this.properties = properties;
  132.             this.propCount = propCount;
  133.             this.needSort = true;
  134.         }
  135.        
  136.         /// <devdoc>
  137.         /// <para>
  138.         /// Gets the number
  139.         /// of property descriptors in the
  140.         /// collection.
  141.         /// </para>
  142.         /// </devdoc>
  143.         public int Count {
  144.             get { return propCount; }
  145.         }
  146.        
  147.         /// <devdoc>
  148.         /// <para>Gets the property with the specified index
  149.         /// number.</para>
  150.         /// </devdoc>
  151.         public virtual PropertyDescriptor this[int index]
  152.         {
  153.             get {
  154.                 if (index >= propCount) {
  155.                     throw new IndexOutOfRangeException();
  156.                 }
  157.                 EnsurePropsOwned();
  158.                 return properties[index];
  159.             }
  160.         }
  161.        
  162.         /// <devdoc>
  163.         /// <para>Gets the property with the specified name.</para>
  164.         /// </devdoc>
  165.         public virtual PropertyDescriptor this[string name]
  166.         {
  167.             get { return Find(name, false); }
  168.         }
  169.        
  170.         /// <devdoc>
  171.         /// <para>[To be supplied.]</para>
  172.         /// </devdoc>
  173.         public int Add(PropertyDescriptor value)
  174.         {
  175.             if (readOnly) {
  176.                 throw new NotSupportedException();
  177.             }
  178.            
  179.             EnsureSize(propCount + 1);
  180.             properties[propCount++] = value;
  181.             return propCount - 1;
  182.         }
  183.        
  184.         /// <devdoc>
  185.         /// <para>[To be supplied.]</para>
  186.         /// </devdoc>
  187.         public void Clear()
  188.         {
  189.             if (readOnly) {
  190.                 throw new NotSupportedException();
  191.             }
  192.            
  193.             propCount = 0;
  194.             cachedFoundProperties = null;
  195.         }
  196.        
  197.         /// <devdoc>
  198.         /// <para>[To be supplied.]</para>
  199.         /// </devdoc>
  200.         public bool Contains(PropertyDescriptor value)
  201.         {
  202.             return IndexOf(value) >= 0;
  203.         }
  204.        
  205.         /// <devdoc>
  206.         /// <para>[To be supplied.]</para>
  207.         /// </devdoc>
  208.         public void CopyTo(Array array, int index)
  209.         {
  210.             EnsurePropsOwned();
  211.             Array.Copy(properties, 0, array, index, Count);
  212.         }
  213.        
  214.         private void EnsurePropsOwned()
  215.         {
  216.             if (!propsOwned) {
  217.                 propsOwned = true;
  218.                 if (properties != null) {
  219.                     PropertyDescriptor[] newProps = new PropertyDescriptor[Count];
  220.                     Array.Copy(properties, 0, newProps, 0, Count);
  221.                     this.properties = newProps;
  222.                 }
  223.             }
  224.            
  225.             if (needSort) {
  226.                 needSort = false;
  227.                 InternalSort(this.namedSort);
  228.             }
  229.         }
  230.        
  231.         private void EnsureSize(int sizeNeeded)
  232.         {
  233.            
  234.             if (sizeNeeded <= properties.Length) {
  235.                 return;
  236.             }
  237.            
  238.             if (properties == null || properties.Length == 0) {
  239.                 propCount = 0;
  240.                 properties = new PropertyDescriptor[sizeNeeded];
  241.                 return;
  242.             }
  243.            
  244.             EnsurePropsOwned();
  245.            
  246.             int newSize = Math.Max(sizeNeeded, properties.Length * 2);
  247.             PropertyDescriptor[] newProps = new PropertyDescriptor[newSize];
  248.             Array.Copy(properties, 0, newProps, 0, propCount);
  249.             properties = newProps;
  250.         }
  251.        
  252.         /// <devdoc>
  253.         /// <para>Gets the description of the property with the specified
  254.         /// name.</para>
  255.         /// </devdoc>
  256.         public virtual PropertyDescriptor Find(string name, bool ignoreCase)
  257.         {
  258.             lock (this) {
  259.                 PropertyDescriptor p = null;
  260.                
  261.                 if (cachedFoundProperties == null || cachedIgnoreCase != ignoreCase) {
  262.                     cachedIgnoreCase = ignoreCase;
  263.                     cachedFoundProperties = new HybridDictionary(ignoreCase);
  264.                 }
  265.                
  266.                 // first try to find it in the cache
  267.                 //
  268.                 object cached = cachedFoundProperties[name];
  269.                
  270.                 if (cached != null) {
  271.                     return (PropertyDescriptor)cached;
  272.                 }
  273.                
  274.                 // Now start walking from where we last left off, filling
  275.                 // the cache as we go.
  276.                 //
  277.                 for (int i = 0; i < propCount; i++) {
  278.                    
  279.                     if (ignoreCase) {
  280.                         if (String.Equals(properties[i].Name, name, StringComparison.OrdinalIgnoreCase)) {
  281.                             cachedFoundProperties[name] = properties[i];
  282.                             p = properties[i];
  283.                             break;
  284.                         }
  285.                     }
  286.                     else {
  287.                         if (properties[i].Name.Equals(name)) {
  288.                             cachedFoundProperties[name] = properties[i];
  289.                             p = properties[i];
  290.                             break;
  291.                         }
  292.                     }
  293.                 }
  294.                
  295.                 return p;
  296.             }
  297.         }
  298.        
  299.         /// <devdoc>
  300.         /// <para>[To be supplied.]</para>
  301.         /// </devdoc>
  302.         public int IndexOf(PropertyDescriptor value)
  303.         {
  304.             return Array.IndexOf(properties, value, 0, propCount);
  305.         }
  306.        
  307.         /// <devdoc>
  308.         /// <para>[To be supplied.]</para>
  309.         /// </devdoc>
  310.         public void Insert(int index, PropertyDescriptor value)
  311.         {
  312.             if (readOnly) {
  313.                 throw new NotSupportedException();
  314.             }
  315.            
  316.             EnsureSize(propCount + 1);
  317.             if (index < propCount) {
  318.                 Array.Copy(properties, index, properties, index + 1, propCount - index);
  319.             }
  320.             properties[index] = value;
  321.             propCount++;
  322.         }
  323.        
  324.         /// <devdoc>
  325.         /// <para>[To be supplied.]</para>
  326.         /// </devdoc>
  327.         public void Remove(PropertyDescriptor value)
  328.         {
  329.             if (readOnly) {
  330.                 throw new NotSupportedException();
  331.             }
  332.            
  333.             int index = IndexOf(value);
  334.            
  335.             if (index != -1) {
  336.                 RemoveAt(index);
  337.             }
  338.         }
  339.        
  340.         /// <devdoc>
  341.         /// <para>[To be supplied.]</para>
  342.         /// </devdoc>
  343.         public void RemoveAt(int index)
  344.         {
  345.             if (readOnly) {
  346.                 throw new NotSupportedException();
  347.             }
  348.            
  349.             if (index < propCount - 1) {
  350.                 Array.Copy(properties, index + 1, properties, index, propCount - index - 1);
  351.             }
  352.             properties[propCount - 1] = null;
  353.             propCount--;
  354.         }
  355.        
  356.         /// <devdoc>
  357.         /// <para>
  358.         /// Sorts the members of this PropertyDescriptorCollection, using the default sort for this collection,
  359.         /// which is usually alphabetical.
  360.         /// </para>
  361.         /// </devdoc>
  362.         public virtual PropertyDescriptorCollection Sort()
  363.         {
  364.             return new PropertyDescriptorCollection(this.properties, this.propCount, this.namedSort, this.comparer);
  365.         }
  366.        
  367.        
  368.         /// <devdoc>
  369.         /// <para>
  370.         /// Sorts the members of this PropertyDescriptorCollection. Any specified NamedSort arguments will
  371.         /// be applied first, followed by sort using the specified IComparer.
  372.         /// </para>
  373.         /// </devdoc>
  374.         public virtual PropertyDescriptorCollection Sort(string[] names)
  375.         {
  376.             return new PropertyDescriptorCollection(this.properties, this.propCount, names, this.comparer);
  377.         }
  378.        
  379.         /// <devdoc>
  380.         /// <para>
  381.         /// Sorts the members of this PropertyDescriptorCollection. Any specified NamedSort arguments will
  382.         /// be applied first, followed by sort using the specified IComparer.
  383.         /// </para>
  384.         /// </devdoc>
  385.         public virtual PropertyDescriptorCollection Sort(string[] names, IComparer comparer)
  386.         {
  387.             return new PropertyDescriptorCollection(this.properties, this.propCount, names, comparer);
  388.         }
  389.        
  390.         /// <devdoc>
  391.         /// <para>
  392.         /// Sorts the members of this PropertyDescriptorCollection, using the specified IComparer to compare,
  393.         /// the PropertyDescriptors contained in the collection.
  394.         /// </para>
  395.         /// </devdoc>
  396.         public virtual PropertyDescriptorCollection Sort(IComparer comparer)
  397.         {
  398.             return new PropertyDescriptorCollection(this.properties, this.propCount, this.namedSort, comparer);
  399.         }
  400.        
  401.         /// <devdoc>
  402.         /// <para>
  403.         /// Sorts the members of this PropertyDescriptorCollection. Any specified NamedSort arguments will
  404.         /// be applied first, followed by sort using the specified IComparer.
  405.         /// </para>
  406.         /// </devdoc>
  407.         protected void InternalSort(string[] names)
  408.         {
  409.             if (properties == null || properties.Length == 0) {
  410.                 return;
  411.             }
  412.            
  413.             this.InternalSort(this.comparer);
  414.            
  415.             if (names != null && names.Length > 0) {
  416.                
  417.                 ArrayList propArrayList = new ArrayList(properties);
  418.                 int foundCount = 0;
  419.                 int propCount = properties.Length;
  420.                
  421.                 for (int i = 0; i < names.Length; i++) {
  422.                     for (int j = 0; j < propCount; j++) {
  423.                         PropertyDescriptor currentProp = (PropertyDescriptor)propArrayList[j];
  424.                        
  425.                         // Found a matching property. Here, we add it to our array. We also
  426.                         // mark it as null in our array list so we don't add it twice later.
  427.                         //
  428.                         if (currentProp != null && currentProp.Name.Equals(names[i])) {
  429.                             properties[foundCount++] = currentProp;
  430.                             propArrayList[j] = null;
  431.                             break;
  432.                         }
  433.                     }
  434.                 }
  435.                
  436.                 // At this point we have filled in the first "foundCount" number of propeties, one for each
  437.                 // name in our name array. If a name didn't match, then it is ignored. Next, we must fill
  438.                 // in the rest of the properties. We now have a sparse array containing the remainder, so
  439.                 // it's easy.
  440.                 //
  441.                 for (int i = 0; i < propCount; i++) {
  442.                     if (propArrayList[i] != null) {
  443.                         properties[foundCount++] = (PropertyDescriptor)propArrayList[i];
  444.                     }
  445.                 }
  446.                
  447.                 Debug.Assert(foundCount == propCount, "We did not completely fill our property array");
  448.             }
  449.         }
  450.        
  451.         /// <devdoc>
  452.         /// <para>
  453.         /// Sorts the members of this PropertyDescriptorCollection using the specified IComparer.
  454.         /// </para>
  455.         /// </devdoc>
  456.         protected void InternalSort(IComparer sorter)
  457.         {
  458.             if (sorter == null) {
  459.                 TypeDescriptor.SortDescriptorArray(this);
  460.             }
  461.             else {
  462.                 Array.Sort(properties, sorter);
  463.             }
  464.         }
  465.        
  466.         /// <devdoc>
  467.         /// <para>
  468.         /// Gets an enumerator for this <see cref='System.ComponentModel.PropertyDescriptorCollection'/>.
  469.         /// </para>
  470.         /// </devdoc>
  471.         public virtual IEnumerator GetEnumerator()
  472.         {
  473.             EnsurePropsOwned();
  474.             // we can only return an enumerator on the props we actually have...
  475.             if (properties.Length != this.propCount) {
  476.                 PropertyDescriptor[] enumProps = new PropertyDescriptor[propCount];
  477.                 Array.Copy(properties, 0, enumProps, 0, propCount);
  478.                 return enumProps.GetEnumerator();
  479.             }
  480.             return properties.GetEnumerator();
  481.         }
  482.        
  483.         /// <internalonly/>
  484.         int ICollection.Count {
  485.             get { return Count; }
  486.         }
  487.        
  488.         /// <internalonly/>
  489.         bool ICollection.IsSynchronized {
  490.             get { return false; }
  491.         }
  492.        
  493.         /// <internalonly/>
  494.         object ICollection.SyncRoot {
  495.             get { return null; }
  496.         }
  497.        
  498.         /// <internalonly/>
  499.         void IDictionary.Add(object key, object value)
  500.         {
  501.             PropertyDescriptor newProp = value as PropertyDescriptor;
  502.            
  503.             if (newProp == null) {
  504.                 throw new ArgumentException("value");
  505.             }
  506.             Add(newProp);
  507.         }
  508.        
  509.         /// <internalonly/>
  510.         void IDictionary.Clear()
  511.         {
  512.             Clear();
  513.         }
  514.        
  515.         /// <internalonly/>
  516.         bool IDictionary.Contains(object key)
  517.         {
  518.             if (key is string) {
  519.                 return this[(string)key] != null;
  520.             }
  521.             return false;
  522.         }
  523.        
  524.         /// <internalonly/>
  525.         IDictionaryEnumerator IDictionary.GetEnumerator()
  526.         {
  527.             return new PropertyDescriptorEnumerator(this);
  528.         }
  529.        
  530.         /// <internalonly/>
  531.         bool IDictionary.IsFixedSize {
  532.             get { return readOnly; }
  533.         }
  534.        
  535.         /// <internalonly/>
  536.         bool IDictionary.IsReadOnly {
  537.             get { return readOnly; }
  538.         }
  539.        
  540.         /// <internalonly/>
  541.         object IDictionary.this[object key]
  542.         {
  543.             get {
  544.                 if (key is string) {
  545.                     return this[(string)key];
  546.                 }
  547.                 return null;
  548.             }
  549.            
  550.             set {
  551.                 if (readOnly) {
  552.                     throw new NotSupportedException();
  553.                 }
  554.                
  555.                 if (value != null && !(value is PropertyDescriptor)) {
  556.                     throw new ArgumentException("value");
  557.                 }
  558.                
  559.                 int index = -1;
  560.                
  561.                 if (key is int) {
  562.                     index = (int)key;
  563.                    
  564.                     if (index < 0 || index >= propCount) {
  565.                         throw new IndexOutOfRangeException();
  566.                     }
  567.                 }
  568.                 else if (key is string) {
  569.                     for (int i = 0; i < propCount; i++) {
  570.                         if (properties[i].Name.Equals((string)key)) {
  571.                             index = i;
  572.                             break;
  573.                         }
  574.                     }
  575.                 }
  576.                 else {
  577.                     throw new ArgumentException("key");
  578.                 }
  579.                
  580.                 if (index == -1) {
  581.                     Add((PropertyDescriptor)value);
  582.                 }
  583.                 else {
  584.                     EnsurePropsOwned();
  585.                     properties[index] = (PropertyDescriptor)value;
  586.                     if (cachedFoundProperties != null && key is string) {
  587.                         cachedFoundProperties[key] = value;
  588.                     }
  589.                 }
  590.             }
  591.         }
  592.        
  593.         /// <internalonly/>
  594.         ICollection IDictionary.Keys {
  595.             get {
  596.                 string[] keys = new string[propCount];
  597.                 for (int i = 0; i < propCount; i++) {
  598.                     keys[i] = properties[i].Name;
  599.                 }
  600.                 return keys;
  601.             }
  602.         }
  603.        
  604.         /// <internalonly/>
  605.         ICollection IDictionary.Values {
  606.             get {
  607.                 // we can only return an enumerator on the props we actually have...
  608.                 //
  609.                 if (properties.Length != this.propCount) {
  610.                     PropertyDescriptor[] newProps = new PropertyDescriptor[propCount];
  611.                     Array.Copy(properties, 0, newProps, 0, propCount);
  612.                     return newProps;
  613.                 }
  614.                 else {
  615.                     return (ICollection)properties.Clone();
  616.                 }
  617.             }
  618.         }
  619.        
  620.         /// <internalonly/>
  621.         void IDictionary.Remove(object key)
  622.         {
  623.             if (key is string) {
  624.                 PropertyDescriptor pd = this[(string)key];
  625.                 if (pd != null) {
  626.                     ((IList)this).Remove(pd);
  627.                 }
  628.             }
  629.         }
  630.        
  631.         /// <internalonly/>
  632.         IEnumerator IEnumerable.GetEnumerator()
  633.         {
  634.             return GetEnumerator();
  635.         }
  636.        
  637.         /// <internalonly/>
  638.         int IList.Add(object value)
  639.         {
  640.             return Add((PropertyDescriptor)value);
  641.         }
  642.        
  643.         /// <internalonly/>
  644.         void IList.Clear()
  645.         {
  646.             Clear();
  647.         }
  648.        
  649.         /// <internalonly/>
  650.         bool IList.Contains(object value)
  651.         {
  652.             return Contains((PropertyDescriptor)value);
  653.         }
  654.        
  655.         /// <internalonly/>
  656.         int IList.IndexOf(object value)
  657.         {
  658.             return IndexOf((PropertyDescriptor)value);
  659.         }
  660.        
  661.         /// <internalonly/>
  662.         void IList.Insert(int index, object value)
  663.         {
  664.             Insert(index, (PropertyDescriptor)value);
  665.         }
  666.        
  667.         /// <internalonly/>
  668.         bool IList.IsReadOnly {
  669.             get { return readOnly; }
  670.         }
  671.        
  672.         /// <internalonly/>
  673.         bool IList.IsFixedSize {
  674.             get { return readOnly; }
  675.         }
  676.        
  677.         /// <internalonly/>
  678.         void IList.Remove(object value)
  679.         {
  680.             Remove((PropertyDescriptor)value);
  681.         }
  682.        
  683.         /// <internalonly/>
  684.         void IList.RemoveAt(int index)
  685.         {
  686.             RemoveAt(index);
  687.         }
  688.        
  689.         /// <internalonly/>
  690.         object IList.this[int index]
  691.         {
  692.             get { return this[index]; }
  693.             set {
  694.                 if (readOnly) {
  695.                     throw new NotSupportedException();
  696.                 }
  697.                
  698.                 if (index >= propCount) {
  699.                     throw new IndexOutOfRangeException();
  700.                 }
  701.                
  702.                
  703.                 if (value != null && !(value is PropertyDescriptor)) {
  704.                     throw new ArgumentException("value");
  705.                 }
  706.                
  707.                 EnsurePropsOwned();
  708.                 properties[index] = (PropertyDescriptor)value;
  709.             }
  710.         }
  711.        
  712.         private class PropertyDescriptorEnumerator : IDictionaryEnumerator
  713.         {
  714.             private PropertyDescriptorCollection owner;
  715.             private int index = -1;
  716.            
  717.             public PropertyDescriptorEnumerator(PropertyDescriptorCollection owner)
  718.             {
  719.                 this.owner = owner;
  720.             }
  721.            
  722.             public object Current {
  723.                 get { return Entry; }
  724.             }
  725.            
  726.             public DictionaryEntry Entry {
  727.                 get {
  728.                     PropertyDescriptor curProp = owner[index];
  729.                     return new DictionaryEntry(curProp.Name, curProp);
  730.                 }
  731.             }
  732.            
  733.             public object Key {
  734.                 get { return owner[index].Name; }
  735.             }
  736.            
  737.             public object Value {
  738.                 get { return owner[index].Name; }
  739.             }
  740.            
  741.             public bool MoveNext()
  742.             {
  743.                 if (index < (owner.Count - 1)) {
  744.                     index++;
  745.                     return true;
  746.                 }
  747.                 return false;
  748.             }
  749.            
  750.             public void Reset()
  751.             {
  752.                 index = -1;
  753.             }
  754.         }
  755.     }
  756. }

Developer Fusion