首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

怎的为PropertyGrid排序(属性类别排序,属性排序)

2013-11-08 
怎样为PropertyGrid排序(属性类别排序,属性排序)有个工具类可以把每个属性类别里的属性排序,但是不能把属

怎样为PropertyGrid排序(属性类别排序,属性排序)
有个工具类可以把每个属性类别里的属性排序,但是不能把属性类别排序。
为属性类添加属性:[TypeConverter(typeof(PropertySorter))]
为每个属性添加属性:[PropertyOrder(10)]
我写了篇博客:http://www.cnblogs.com/greatverve/archive/2012/02/08/propergrid-order.html
请教:怎样把属性类别排序?谢谢。


private void Form_Load(object sender, EventArgs e)
{
    propertyGrid1.SelectedObject = new Person();
}
[TypeConverter(typeof(PropertySorter))]
[DefaultProperty("Name")]
public class Person
{
    protected const string PERSONAL_CAT = "Personal Details";
    
    private string _name = "Bob";
    private DateTime _birthday = new DateTime(1975,1,1);

    [Category(PERSONAL_CAT), PropertyOrder(10)]
    public string Name
    {
        get {return _name;} 
        set {_name = value;} 
    }

    [Category(PERSONAL_CAT), PropertyOrder(11)]
    public DateTime Birthday
    {
        get {return _birthday;}
        set {_birthday = value;}
    }

    [Category(PERSONAL_CAT), PropertyOrder(12)]
    public int Age
    {
        get 
        {
            TimeSpan age = DateTime.Now - _birthday; 
            return (int)age.TotalDays / 365; 
        }
    }
}

工具类:

//
// (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
}


[解决办法]
貌似不支持自定义,事实上这种需求基本不会有,拼音排序已经很合理了,因此微软也就没提供支持。
你可以考虑变通的方法,汉字本身对于一种意思有多种表示写法,追求一种能达到排序的单词组合。实在不行就在分类名前加阿拉伯数字,表示排序。
[解决办法]
属性类别排序?不是很理解啊 
[解决办法]
有一个投机但很简单的方法,目前PropertyGrid不显示制表符(\t),因此可以简单的附加一个或多个\t,使得某些类别排在前面。

class My
{
    [Category("Advanced")]
    public int Age { get; set; }

    [Category("\tGeneral")]       //<--
    public string Name { get; set; }
}

[解决办法]
本人研究出了一个方法,不过比较复杂,可以参考:

        public Form1()
        {
            InitializeComponent();

            propertyGrid1.SelectedObjectsChanged += new EventHandler(propertyGrid1_SelectedObjectsChanged);
            propertyGrid1.SelectedObject = new Person();
        }

        void propertyGrid1_SelectedObjectsChanged(object sender, EventArgs e)
        {
            propertyGrid1.Tag = propertyGrid1.PropertySort;
            propertyGrid1.PropertySort = PropertySort.CategorizedAlphabetical;
            propertyGrid1.Paint += new PaintEventHandler(propertyGrid1_Paint);            
        }

        void propertyGrid1_Paint(object sender, PaintEventArgs e)
        {
            var categorysinfo = propertyGrid1.SelectedObject.GetType().GetField("categorys", BindingFlags.NonPublic 
[解决办法]
 BindingFlags.Instance);
            if (categorysinfo != null)
            {
                var categorys = categorysinfo.GetValue(propertyGrid1.SelectedObject) as List<String>;
                propertyGrid1.CollapseAllGridItems();
                GridItemCollection currentPropEntries = propertyGrid1.GetType().GetField("currentPropEntries", BindingFlags.NonPublic 


[解决办法]
 BindingFlags.Instance).GetValue(propertyGrid1) as GridItemCollection;
                var newarray = currentPropEntries.Cast<GridItem>().OrderBy((t) => categorys.IndexOf(t.Label)).ToArray();
                currentPropEntries.GetType().GetField("entries", BindingFlags.NonPublic 
[解决办法]
 BindingFlags.Instance).SetValue(currentPropEntries, newarray);
                propertyGrid1.ExpandAllGridItems();
                propertyGrid1.PropertySort = (PropertySort)propertyGrid1.Tag;
            }
            propertyGrid1.Paint -= new PaintEventHandler(propertyGrid1_Paint);
        }

    [TypeConverter(typeof(PropertySorter))]
    [DefaultProperty("Name")]
    public class Person
    {
        private List<string> categorys = new List<string>() { "B", "A", "C" };
        private string _name = "Bob";
        private DateTime _birthday = new DateTime(1975, 1, 1);

        [Category("A"), PropertyOrder(10)]
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        [Category("B"), PropertyOrder(11)]
        public DateTime Birthday
        {
            get { return _birthday; }
            set { _birthday = value; }
        }

        [Category("C"), PropertyOrder(12)]
        public int Age
        {
            get
            {
                TimeSpan age = DateTime.Now - _birthday;
                return (int)age.TotalDays / 365;
            }
        }
    }


只要给自己的类添加categorys 私有成员变量(名字也可以换个不常用的,防止被占用),即可按照这个List<String>中的出现顺序来排序了。无需任何多余的说明,没有该变量就不排序,但是不支持属性弹出窗口中的PropertyGrid,除非你自定义弹出窗口,添加那些处理事件。
[解决办法]
引用:
本人研究出了一个方法,不过比较复杂,可以参考:
C# code

        public Form1()
        {
            InitializeComponent();

            propertyGrid1.SelectedObjectsChanged += new EventHandler(propertyGrid1_SelectedObje……


这个不错

热点排行