Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1412 | chris | 1 | // |
| 2 | // (C) Paul Tingey 2004 |
||
| 3 | // |
||
| 4 | using System; |
||
| 5 | using System.Collections; |
||
| 6 | using System.ComponentModel; |
||
| 7 | |||
| 8 | namespace OrderedPropertyGrid |
||
| 9 | { |
||
| 10 | public class PropertySorter : ExpandableObjectConverter |
||
| 11 | { |
||
| 12 | #region Methods |
||
| 13 | public override bool GetPropertiesSupported(ITypeDescriptorContext context) |
||
| 14 | { |
||
| 15 | return true; |
||
| 16 | } |
||
| 17 | |||
| 18 | public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) |
||
| 19 | { |
||
| 20 | // |
||
| 21 | // This override returns a list of properties in order |
||
| 22 | // |
||
| 23 | PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(value, attributes); |
||
| 24 | ArrayList orderedProperties = new ArrayList(); |
||
| 25 | foreach (PropertyDescriptor pd in pdc) |
||
| 26 | { |
||
| 27 | Attribute attribute = pd.Attributes[typeof(PropertyOrderAttribute)]; |
||
| 28 | if (attribute != null) |
||
| 29 | { |
||
| 30 | // |
||
| 31 | // If the attribute is found, then create an pair object to hold it |
||
| 32 | // |
||
| 33 | PropertyOrderAttribute poa = (PropertyOrderAttribute)attribute; |
||
| 34 | orderedProperties.Add(new PropertyOrderPair(pd.Name,poa.Order)); |
||
| 35 | } |
||
| 36 | else |
||
| 37 | { |
||
| 38 | // |
||
| 39 | // If no order attribute is specifed then given it an order of 0 |
||
| 40 | // |
||
| 41 | orderedProperties.Add(new PropertyOrderPair(pd.Name,0)); |
||
| 42 | } |
||
| 43 | } |
||
| 44 | // |
||
| 45 | // Perform the actual order using the value PropertyOrderPair classes |
||
| 46 | // implementation of IComparable to sort |
||
| 47 | // |
||
| 48 | orderedProperties.Sort(); |
||
| 49 | // |
||
| 50 | // Build a string list of the ordered names |
||
| 51 | // |
||
| 52 | ArrayList propertyNames = new ArrayList(); |
||
| 53 | foreach (PropertyOrderPair pop in orderedProperties) |
||
| 54 | { |
||
| 55 | propertyNames.Add(pop.Name); |
||
| 56 | } |
||
| 57 | // |
||
| 58 | // Pass in the ordered list for the PropertyDescriptorCollection to sort by |
||
| 59 | // |
||
| 60 | return pdc.Sort((string[])propertyNames.ToArray(typeof(string))); |
||
| 61 | } |
||
| 62 | #endregion |
||
| 63 | } |
||
| 64 | |||
| 65 | #region Helper Class - PropertyOrderAttribute |
||
| 66 | [AttributeUsage(AttributeTargets.Property)] |
||
| 67 | public class PropertyOrderAttribute : Attribute |
||
| 68 | { |
||
| 69 | // |
||
| 70 | // Simple attribute to allow the order of a property to be specified |
||
| 71 | // |
||
| 72 | private int _order; |
||
| 73 | public PropertyOrderAttribute(int order) |
||
| 74 | { |
||
| 75 | _order = order; |
||
| 76 | } |
||
| 77 | |||
| 78 | public int Order |
||
| 79 | { |
||
| 80 | get |
||
| 81 | { |
||
| 82 | return _order; |
||
| 83 | } |
||
| 84 | } |
||
| 85 | } |
||
| 86 | #endregion |
||
| 87 | |||
| 88 | #region Helper Class - PropertyOrderPair |
||
| 89 | public class PropertyOrderPair : IComparable |
||
| 90 | { |
||
| 91 | private int _order; |
||
| 92 | private string _name; |
||
| 93 | public string Name |
||
| 94 | { |
||
| 95 | get |
||
| 96 | { |
||
| 97 | return _name; |
||
| 98 | } |
||
| 99 | } |
||
| 100 | |||
| 101 | public PropertyOrderPair(string name, int order) |
||
| 102 | { |
||
| 103 | _order = order; |
||
| 104 | _name = name; |
||
| 105 | } |
||
| 106 | |||
| 107 | public int CompareTo(object obj) |
||
| 108 | { |
||
| 109 | // |
||
| 110 | // Sort the pair objects by ordering by order value |
||
| 111 | // Equal values get the same rank |
||
| 112 | // |
||
| 113 | int otherOrder = ((PropertyOrderPair)obj)._order; |
||
| 114 | if (otherOrder == _order) |
||
| 115 | { |
||
| 116 | // |
||
| 117 | // If order not specified, sort by name |
||
| 118 | // |
||
| 119 | string otherName = ((PropertyOrderPair)obj)._name; |
||
| 120 | return string.Compare(_name,otherName); |
||
| 121 | } |
||
| 122 | else if (otherOrder > _order) |
||
| 123 | { |
||
| 124 | return -1; |
||
| 125 | } |
||
| 126 | return 1; |
||
| 127 | } |
||
| 128 | } |
||
| 129 | #endregion |
||
| 130 | } |