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
}