PropertyGrid空间开发总结四

 属性排序方式

属性的排序是基于容器类的.sort();实现的。因为控件通过TypeConverter.GetProperties();方法获得PropertyDescriptorCollection类型的对象。并根据此对象的元素设定SelectedObject的表现方式等。故实现属性类的排序首先需要获得对象的集合,然后使其按指定方式排序。因为sort()方法接受string[]类型的参数作为排序依据,其相对于属性的排序是比对其Name属性(或DisplayName属性),而我们需要在保证本地化的前提下完成排序,所以我们要在抛开其Name属性(或者DisplayName)的前提下实现排序(理论上我们能获得属性property的name属性,即方法名,但是笔者在实践中设定字符串数组中依次填入name作为排序依据,未能成功,非本地化的情况下可以实现,现在仍未找到原因,猜测其可能会以DisplayName替代Name返回???)。基于以上分析与原因,我们需要给每个属性Property添加一个属性Attribute可以作为排序的依据。到此,存在一个问题。如何根据新的属性(代称为order)对Property进行排序。较为优雅的方法是实现IComparable()接口。

事例代码如下:(部分代码来源于网络,感谢先辈)

 [AttributeUsage(AttributeTargets.Property)]
    public class PropertyOrderAttribute : Attribute//自定义Attribute类,向property提供

```````````````````````````````````````````````````//order属性
    {
        private int order;

        public PropertyOrderAttribute(int order)
        {
            this.order = order;
        }

        public int Order
        {
            get
            {
                return order;
            }
        }
    }

 

 class TestPropertyDescriptor : PropertyDescriptor,IComparable//继承PropertyDescriptor类并实现IComparable接口
    {
        private PropertyDescriptor basePropertyDescriptor;
        private int order;
        ...

                //构造函数

        public TestPropertyDescriptor(PropertyDescriptor basePropertyDescriptor): base(basePropertyDescriptor)
        {
            this.basePropertyDescriptor = basePropertyDescriptor;
            order = GetOrder(basePropertyDescriptor.Attributes);
        }

                //获得property的order属性

        private int GetOrder(AttributeCollection ac)
        {
            foreach (Attribute a in ac)
            {
                if (a is PropertyOrderAttribute)
                    return ((PropertyOrderAttribute)a).Order;
            }
            return 0;

        }

        
        ...

        #region "IComparable"
        public int CompareTo(object tpd)//实现接口,使此类的对象可以依据order进行比较、排序
        {
            TestPropertyDescriptor other = (TestPropertyDescriptor)tpd;
            if (order == other.order) return string.Compare(Name, other.Name);
            else return (order > other.order) ? 1 : -1;
        }
        #endregion
    }

 

   

 

class ICustomTDClass1: Class1 , ICustomTypeDescriptor//Class1为需要对其属性进行排序的自定义类。

{

...

 public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
       {

            PropertyDescriptorCollection tmpPDC = TypeDescriptor.GetProperties(typeof(ICustomTDClass1), attributes);
            PropertyDescriptorCollection result = new PropertyDescriptorCollection(null);
            ArrayList orderPdList = new ArrayList();

            foreach (PropertyDescriptor pd in tmpPDC)
            {
                 TestPropertyDescriptor tpd = new TestPropertyDescriptor(pd);
                 result.Add(tpd);
                 orderPdList.Add(tpd);

            }
            orderPdList.Sort();//根据order排序
            ArrayList propertyNames = new ArrayList();
            foreach (TestPropertyDescriptor propertyAttributes in orderPdList)//获得排序后的DisplayName数组
            {
                propertyNames.Add(propertyAttributes.DisplayName);
            }

            return result.Sort((string[])propertyNames.ToArray(typeof(string)));//根据数组对结果排序,注意这里不能直接return `````````````````````````````````````````````````````````````````````````````````````````````//result.Sort(),因为在result里存着的是PropertyDescriptor类`````````````````````````````````````````````````````````````````````````````````````````````//型的对象,而不是我们定义的TestPropertyDescriptor类`````````````````````````````````````````````````````````````````````````````````````````````//型。至此,排序功能圆满完成。
        }
...

}

 

PS:并不是所有待排序的类都要重写ICustomTypeDescriptor,更加简洁的方法是自定义TypyConverter类,并在其中的GetProperties(........){}中实现(不是GetProperties(){})。再次感谢先辈们。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值