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
}