using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SigmaDrawerStyle { /// /// 属性排序类 /// /// public class PropertySorter : ExpandableObjectConverter { #region Methods /// public override bool GetPropertiesSupported(ITypeDescriptorContext context) { return true; } public static Dictionary GlobalPropertyDescriptor = new Dictionary(); /// public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) { Type typeObj = value.GetType(); if (GlobalPropertyDescriptor.TryGetValue(typeObj, out PropertyDescriptorCollection properties)) { return properties; } // 原始属性 PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(value, attributes); List orderedProperties = new List(); List lstOriginCategory = new List(); List lstCategoryTab = new List(); List lstCategoryNoTab = new List(); foreach (PropertyDescriptor pd in pdc) { Attribute attribute = pd.Attributes[typeof(PropertyOrderAttribute)]; string strCategory = pd.Category; if (attribute != null) { PropertyOrderAttribute poa = (PropertyOrderAttribute)attribute; orderedProperties.Add(new PropertyOrderPair(pd.Name, poa.Order, strCategory)); } else { // 没有序号的设置序号为 0 orderedProperties.Add(new PropertyOrderPair(pd.Name, 0, strCategory)); } if (!lstOriginCategory.Contains(strCategory)) { lstOriginCategory.Add(strCategory); if (strCategory.IndexOf('\t') >= 0) { lstCategoryTab.Add(strCategory); } else { lstCategoryNoTab.Add(strCategory); } } } List lstCategoryTabFinal = new List(); List lstCategoryNoTabFinal = new List(); if (lstCategoryNoTab.Count > 1) { //char chNull = (char)0x0009; char chNull = '\u200B'; lstCategoryTab.Sort(); for (int i = 0; i < lstCategoryTab.Count; i++) { string strCategory = lstCategoryTab[i]; strCategory = strCategory.Trim('\t'); strCategory = strCategory.PadLeft(strCategory.Length + lstOriginCategory.Count - i - 1, chNull); lstCategoryTabFinal.Add(strCategory); } for (int i = 0; i < lstCategoryNoTab.Count; i++) { string strCategory = lstCategoryNoTab[i]; strCategory = strCategory.PadLeft(strCategory.Length + lstOriginCategory.Count - lstCategoryTab.Count - i - 1, chNull); lstCategoryNoTabFinal.Add(strCategory); } } List finalList = new List(); foreach (PropertyDescriptor pd in pdc) { string strCagegory = pd.Category; if (lstCategoryNoTab.Count > 1) { int nIndex = lstCategoryTab.IndexOf(strCagegory); if (nIndex >= 0) { strCagegory = lstCategoryTabFinal[nIndex]; } else { nIndex = lstCategoryNoTab.IndexOf(strCagegory); if (nIndex >= 0) { strCagegory = lstCategoryNoTabFinal[nIndex]; } } } var attrs = new Attribute[pd.Attributes.Count]; pd.Attributes.CopyTo(attrs, 0); // 更新CategoryAttribute for (int j = 0; j < attrs.Length; j++) { if (attrs[j] is CategoryAttribute) { attrs[j] = new CategoryAttribute(strCagegory); break; } } finalList.Add(TypeDescriptor.CreateProperty( pd.ComponentType, pd, attrs)); } // 重新设置类别属性 orderedProperties.Sort(); int nPropertyCount = orderedProperties.Count; string[] saOrderNames = new string[nPropertyCount]; for (int i = 0; i < nPropertyCount; i++) { saOrderNames[i] = orderedProperties[i].Name; } PropertyDescriptorCollection result = new PropertyDescriptorCollection(finalList.ToArray(), true).Sort(saOrderNames); GlobalPropertyDescriptor.Add(typeObj, result); return result; } #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; /// /// Initializes a new instance of the class. /// /// 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 Category { get; set; } public string Name { get { return _name; } } /// /// Initializes a new instance of the class. /// /// 名称 /// 顺序号 public PropertyOrderPair(string name, int order) { _order = order; _name = name; } /// /// Initializes a new instance of the class. /// /// 名称. /// 序号. /// 分类. public PropertyOrderPair(string name, int order, string category) : this(name, order) { this.Category = category; } 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 }