www.pudn.com > OrderedPropertyGrid_src.zip > PropertySorter.cs


// 
// (C) Paul Tingey 2004  
// 
using System; 
using System.Collections; 
using System.ComponentModel; 
 
namespace OrderedPropertyGrid 
{ 
    public class PropertySorter : ExpandableObjectConverter 
    { 
        #region Methods 
        public override bool GetPropertiesSupported(ITypeDescriptorContext context)  
        { 
            return true; 
        } 
 
        public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) 
        { 
            // 
            // This override returns a list of properties in order 
            // 
            PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(value, attributes); 
            ArrayList orderedProperties = new ArrayList(); 
            foreach (PropertyDescriptor pd in pdc) 
            { 
                Attribute attribute = pd.Attributes[typeof(PropertyOrderAttribute)]; 
                if (attribute != null) 
                { 
                    // 
                    // If the attribute is found, then create an pair object to hold it 
                    // 
                    PropertyOrderAttribute poa = (PropertyOrderAttribute)attribute; 
                    orderedProperties.Add(new PropertyOrderPair(pd.Name,poa.Order)); 
                } 
                else 
                { 
                    // 
                    // If no order attribute is specifed then given it an order of 0 
                    // 
                    orderedProperties.Add(new PropertyOrderPair(pd.Name,0)); 
                } 
            } 
            // 
            // Perform the actual order using the value PropertyOrderPair classes 
            // implementation of IComparable to sort 
            // 
            orderedProperties.Sort(); 
            // 
            // Build a string list of the ordered names 
            // 
            ArrayList propertyNames = new ArrayList(); 
            foreach (PropertyOrderPair pop in orderedProperties) 
            { 
                propertyNames.Add(pop.Name); 
            } 
            // 
            // Pass in the ordered list for the PropertyDescriptorCollection to sort by 
            // 
            return pdc.Sort((string[])propertyNames.ToArray(typeof(string))); 
        } 
        #endregion 
    } 
 
    #region Helper Class - PropertyOrderAttribute 
    [AttributeUsage(AttributeTargets.Property)] 
    public class PropertyOrderAttribute : Attribute 
    { 
        // 
        // Simple attribute to allow the order of a property to be specified 
        // 
        private int _order; 
        public PropertyOrderAttribute(int order) 
        { 
            _order = order; 
        } 
 
        public int Order 
        { 
            get 
            { 
                return _order; 
            } 
        } 
    } 
    #endregion 
 
    #region Helper Class - PropertyOrderPair 
    public class PropertyOrderPair : IComparable 
    { 
        private int _order; 
        private string _name; 
        public string Name 
        { 
            get 
            { 
                return _name; 
            } 
        } 
 
        public PropertyOrderPair(string name, int order) 
        { 
            _order = order; 
            _name = name; 
        } 
 
        public int CompareTo(object obj) 
        { 
            // 
            // Sort the pair objects by ordering by order value 
            // Equal values get the same rank 
            // 
            int otherOrder = ((PropertyOrderPair)obj)._order; 
            if (otherOrder == _order) 
            { 
                // 
                // If order not specified, sort by name 
                // 
                string otherName = ((PropertyOrderPair)obj)._name; 
                return string.Compare(_name,otherName); 
            } 
            else if (otherOrder > _order) 
            { 
                return -1; 
            } 
            return 1; 
        } 
    } 
    #endregion 
}