前些天,由於在項目中需要用到PropertyGrid這個控件,展現其所在控件的某些屬性,由於有些控件的屬性較多,不易瀏覽,而且PropertyGrid的排序默認的按照字母的順序排列的,這樣導致在在某些屬性想要排在第一位非常不方便,於是我總結了網友們的一些思路,自己便解決呢!現在來說說解決思路:
1.首先為PropertyGrid添加SelectedObjectsChanged事件!

1 private void propertyGrid_flow_SelectedObjectsChanged(object sender, EventArgs e) 2 { 3 propertyGrid_flow.Tag = propertyGrid_flow.PropertySort; 4 propertyGrid_flow.PropertySort = PropertySort.CategorizedAlphabetical; 5 propertyGrid_flow.Paint += new PaintEventHandler(propertyGrid_flow_Paint); 6 }
2.為PropertyGrid添加Paint事件! 這其中就是最核心的代碼,就是按照propertyGrid默認屬性排序!

1 var categorysinfo = propertyGrid_flow.SelectedObject.GetType().GetField("categorys", BindingFlags.NonPublic | BindingFlags.Instance); 2 if (categorysinfo != null) 3 { 4 var categorys = categorysinfo.GetValue(propertyGrid_flow.SelectedObject) as List<String>; 5 propertyGrid_flow.CollapseAllGridItems(); 6 GridItemCollection currentPropEntries = propertyGrid_flow.GetType().GetField("currentPropEntries", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(propertyGrid_flow) as GridItemCollection; 7 var newarray = currentPropEntries.Cast<GridItem>().OrderBy((t) => categorys.IndexOf(t.Label)).ToArray(); 8 currentPropEntries.GetType().GetField("entries", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(currentPropEntries, newarray); 9 propertyGrid_flow.ExpandAllGridItems(); 10 propertyGrid_flow.PropertySort = (PropertySort)propertyGrid_flow.Tag; 11 } 12 propertyGrid_flow.Paint -= new PaintEventHandler(propertyGrid_flow_Paint);
3.在其中可以看到有個“categorys”變量,其中是是在propertyGrid的屬性中命名:
[TypeConverter(typeof(PropertySorter))]
public class UctlNodeStepProperty : PropertyGird
{
private List<string> categorys = new List<string>(){ "A", "B", "C", "D" };
}
4. 羅列propertyGrid的屬性:

1 private string _a1=""; 2 private string _a2=""; 3 private string _a3=""; 4 private string _b1=""; 5 private string _c1=""; 6 private string _d1=""; 7 8 9 [Browsable(true), Category("A"), ShowChinese("描述"),PropertyOrder(1)] 10 public string A1 11 { 12 get { return _a1; } 13 set { _a1 = value; } 14 } 15 [Browsable(true), Category("A"), ShowChinese("描述"),PropertyOrder(2)] 16 public string A2 17 { 18 get { return _a2; } 19 set { _a2 = value; } 20 } 21 [Browsable(true), Category("A"), ShowChinese("描述"),PropertyOrder(3)] 22 public string A3 23 { 24 get { return _a3; } 25 set { _a3 = value; } 26 } 27 [Browsable(true), Category("B"), ShowChinese("描述")] 28 public string B1 29 { 30 get { return _b1; } 31 set { _b1 = value; } 32 } 33 [Browsable(true), Category("C"), ShowChinese("描述")] 34 public string C1 35 { 36 get { return _c1; } 37 set { _c1 = value; } 38 } 39 [Browsable(true), Category("D"), ShowChinese("描述")] 40 public string D1 41 { 42 get { return _d1; } 43 set { _d1 = value; } 44 }
5.我想大家也看到了其中的代碼,其中有個屬性“PropertyOrder”,下面就是PropertyOtder類的代碼:

1 public class PropertySorter : ExpandableObjectConverter 2 { 3 #region Methods 4 public override bool GetPropertiesSupported(ITypeDescriptorContext context) 5 { 6 return true; 7 } 8 9 public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) 10 { 11 // 12 // This override returns a list of properties in order 13 // 14 PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(value, attributes); 15 ArrayList orderedProperties = new ArrayList(); 16 foreach (PropertyDescriptor pd in pdc) 17 { 18 Attribute attribute = pd.Attributes[typeof(PropertyOrderAttribute)]; 19 if (attribute != null) 20 { 21 // 22 // If the attribute is found, then create an pair object to hold it 23 // 24 PropertyOrderAttribute poa = (PropertyOrderAttribute)attribute; 25 orderedProperties.Add(new PropertyOrderPair(pd.Name,poa.Order)); 26 } 27 else 28 { 29 // 30 // If no order attribute is specifed then given it an order of 0 31 // 32 orderedProperties.Add(new PropertyOrderPair(pd.Name,0)); 33 } 34 } 35 // 36 // Perform the actual order using the value PropertyOrderPair classes 37 // implementation of IComparable to sort 38 // 39 orderedProperties.Sort(); 40 41 42 // 43 // Build a string list of the ordered names 44 // 45 ArrayList propertyNames = new ArrayList(); 46 foreach (PropertyOrderPair pop in orderedProperties) 47 { 48 propertyNames.Add(pop.Name); 49 } 50 // 51 // Pass in the ordered list for the PropertyDescriptorCollection to sort by 52 // 53 return pdc.Sort((string[])propertyNames.ToArray(typeof(string))); 54 } 55 #endregion 56 } 57 58 #region Helper Class - PropertyOrderAttribute 59 [AttributeUsage(AttributeTargets.Property)] 60 public class PropertyOrderAttribute : Attribute 61 { 62 // 63 // Simple attribute to allow the order of a property to be specified 64 // 65 private int _order; 66 public PropertyOrderAttribute(int order) 67 { 68 _order = order; 69 } 70 71 public int Order 72 { 73 get 74 { 75 return _order; 76 } 77 } 78 } 79 #endregion 80 81 #region Helper Class - PropertyOrderPair 82 public class PropertyOrderPair : IComparable 83 { 84 private int _order; 85 private string _name; 86 public string Name 87 { 88 get 89 { 90 return _name; 91 } 92 } 93 94 public PropertyOrderPair(string name, int order) 95 { 96 _order = order; 97 _name = name; 98 } 99 100 public int CompareTo(object obj) 101 { 102 // 103 // Sort the pair objects by ordering by order value 104 // Equal values get the same rank 105 // 106 int otherOrder = ((PropertyOrderPair)obj)._order; 107 if (otherOrder == _order) 108 { 109 // 110 // If order not specified, sort by name 111 // 112 string otherName = ((PropertyOrderPair)obj)._name; 113 return string.Compare(_name,otherName); 114 } 115 else if (otherOrder > _order) 116 { 117 return -1; 118 } 119 return 1; 120 } 121 } 122 #endregion
6.如果想隱藏Font這樣的屬性的一些英文屬性,僅保留中文屬性的話:(因為按照上面的步驟,你會發現,像Font這樣的屬性會同時包含中文和因為的屬性,發現英文的會有點多余)
public class HideFontSubPropConverter : FontConverter
{
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
return new PropertyDescriptorCollection(null);
}
}
/// <summary>
/// string不展開
/// </summary>
public class HideStringSubPropConverter : StringConverter
{
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
return new PropertyDescriptorCollection(null);
}
}
/// <summary>
/// size不展開
/// </summary>
public class HideSizeSubPropConverter : SizeConverter
{
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
return new PropertyDescriptorCollection(null); ;
}
}