怎样为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
}
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;
}
}
}