c# PropertyGrid 自定义属性排序
生活随笔
收集整理的這篇文章主要介紹了
c# PropertyGrid 自定义属性排序
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?PropertyGrid屬性如果不自定義順序的話,屬性會按照字母順序排序。實際中這并不是想要的結果。可以通過增加一個PropertyOrder的方法,自定義屬性的屬性。這樣就可以根據自己的意愿進行排序了。我先上一個Winform版本的PropertyGrid。過幾天再上一個WPF版本的PropertyGrid排序。Wpf版本的排序將采用開源控件庫HandyControl作為基礎。它可以帶來更好的展示。話不多說,先看下排序前后的效果:
?還是排序后的效果看著舒服。
工程如下:
源碼非常的簡單。拖拽一個PropertyGrid控件,名稱PropertyGrid1。添加兩個類。都是為了屬性排序服務的。
Form1.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Collections;namespace TestWindowForm {public partial class Form1 : Form{public Form1(){InitializeComponent();}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 = "個人信息";private string _name = "約翰";private DateTime _birthday = new DateTime(1985, 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;}}}} }PropertyOrderAttribute.cs:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.ComponentModel; using System.Collections;namespace TestWindowForm {[AttributeUsage(AttributeTargets.Property)]public class PropertyOrderAttribute : Attribute//自定義Attribute類,向property提供{private int order;public PropertyOrderAttribute(int order){this.order = order;}public int Order{get{return order;}}}#region Helper Class - PropertyOrderPairpublic 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;}}#endregionclass 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;}public override bool CanResetValue(object component){return false;}public override Type ComponentType{get{return this.GetType();}}public override object GetValue(object component){return component;}public override bool IsReadOnly{get{return false;}}public override Type PropertyType{get{return this.GetType();}}public override void ResetValue(object component){//不重置,無動作 }public override void SetValue(object component, object value){;}/// <summary>/// 是否應該持久化保存/// </summary>/// <param name="component"></param>/// <returns></returns>public override bool ShouldSerializeValue(object component){return false;}/// <summary>/// 屬性說明/// </summary>public override string Description{get{return this.Description;}}#endregion}class ICustomTDClass1 : 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 }public AttributeCollection GetAttributes(){return TypeDescriptor.GetAttributes(this, true);}public string GetClassName(){return TypeDescriptor.GetClassName(this, true);}public string GetComponentName(){return TypeDescriptor.GetClassName(this, true);}public TypeConverter GetConverter(){return TypeDescriptor.GetConverter(this, true);}public EventDescriptor GetDefaultEvent(){return TypeDescriptor.GetDefaultEvent(this, true);}public PropertyDescriptor GetDefaultProperty(){return TypeDescriptor.GetDefaultProperty(this, true);}public object GetEditor(Type editorBaseType){return TypeDescriptor.GetEditor(this, editorBaseType, true);}public EventDescriptorCollection GetEvents(Attribute[] attributes){return TypeDescriptor.GetEvents(this, attributes, true);}public EventDescriptorCollection GetEvents(){return TypeDescriptor.GetEvents(this, true);}public PropertyDescriptorCollection GetProperties(){return TypeDescriptor.GetProperties(this, true);}public object GetPropertyOwner(PropertyDescriptor pd){return this;}} }PropertySorter.cs:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace TestWindowForm {public class PropertySorter : ExpandableObjectConverter{#region Methodspublic 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} }工程地址:
C#PropertyGrid屬性排序Demo-C#文檔類資源-CSDN下載
總結
以上是生活随笔為你收集整理的c# PropertyGrid 自定义属性排序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 简单的文本挖掘-用于QQ聊天记录(R)
- 下一篇: android 打开系统键盘的方法