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) { // 1. 动态逻辑必须禁用缓存,否则状态切换无法实时生效 // Type typeObj = value.GetType(); // if (GlobalPropertyDescriptor.TryGetValue(typeObj, out PropertyDescriptorCollection properties)) // { // return properties; // } // 2. 获取原始属性 PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(value, attributes); // 3. 动态获取当前对象的 RulerDataStyle 值(使用反射避免命名空间引用错误) int currentStyle = -1; var styleProp = pdc["RulerDataStyle"]; if (styleProp != null) { var val = styleProp.GetValue(value); if (val != null) currentStyle = Convert.ToInt32(val); } // 原始属性 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 attrList = new List(); foreach (Attribute attr in pd.Attributes) { if (attr is CategoryAttribute) { attrList.Add(new CategoryAttribute(strCagegory)); } else { attrList.Add(attr); } } // 逻辑:如果当前属性是 RulerNumber,且检测到的 Style 为 1 或 2 动态设置 RulerNumber 为只读 if (pd.Name == "RulerNumber" && (currentStyle == 1 || currentStyle == 2)) { attrList.RemoveAll(a => a is ReadOnlyAttribute); attrList.Add(new ReadOnlyAttribute(true)); } // -------------------------------------------- finalList.Add(TypeDescriptor.CreateProperty(pd.ComponentType, pd, attrList.ToArray())); } // 重新设置类别属性 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) 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 }