using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace GeoSigma.SigmaDrawerStyle.Converter { public abstract class BaseConverter : TypeConverter where T : TypeConverter, new() { #region Proxy private T _proxy = new T(); public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return _proxy.CanConvertFrom(context, sourceType); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return _proxy.CanConvertTo(context, destinationType); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { return _proxy.ConvertFrom(context, culture, value); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { return _proxy.ConvertTo(context, culture, value, destinationType); } public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues) { return _proxy.CreateInstance(context, propertyValues); } public override bool GetCreateInstanceSupported(ITypeDescriptorContext context) { return _proxy.GetCreateInstanceSupported(context); } public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { return _proxy.GetStandardValues(context); } public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { return _proxy.GetStandardValuesExclusive(context); } public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { return _proxy.GetStandardValuesSupported(context); } public override bool IsValid(ITypeDescriptorContext context, object value) { return _proxy.IsValid(context, value); } public override bool GetPropertiesSupported(ITypeDescriptorContext context) { return _proxy.GetPropertiesSupported(context); } public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) { return _proxy.GetProperties(context, value, attributes); } #endregion } public class BaseTypeConverter : BaseConverter { } public class BaseExpandableConverter : BaseConverter { } public class BaseExpandableReadonlyConverter : BaseConverter { public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) { Type type = typeof(System.ComponentModel.ReadOnlyAttribute); PropertyDescriptorCollection descs = TypeDescriptor.GetProperties(value, attributes); for (int i = 0;i < descs.Count; i++) { PropertyDescriptorCollection descsCol = TypeDescriptor.GetProperties(descs[i], attributes); var prop = descsCol["IsReadOnly"]; prop.SetValue(type, true); } //AttributeCollection attrs = descs["ReadOnly"].Attributes; //FieldInfo fld = type.GetField("isReadOnly", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance); //fld.SetValue(attrs[type], true); //Type memberDescriptorType = typeof(MemberDescriptor); //FieldInfo memberDescriptorFieldInfo = memberDescriptorType.GetField("IsReadOnly" // , BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance); //Type type = value.GetType(); //string strType = type.ToString(); ////Type.GetType(strType); //var model = Activator.CreateInstance(type); //PropertyInfo[] properties = type.GetProperties(); //for (int i=0;i< properties.Length; i++) //{ // Trace.WriteLine(properties[i].Name); //} //properties[0].SetValue(model, true, null); //FieldInfo fld = type.GetField("IsReadOnly", BindingFlags.Static | BindingFlags.Public); //PropertyDescriptorCollection cols = TypeDescriptor.GetProperties(value, attributes); //FieldInfo[] fieldInfos = type.GetFields(); //for (int i = 0; i < cols.Count; i++) //{ // var vv = cols[i].GetType().GetRuntimeField("IsReadOnly"); // var old = fld.GetValue(cols[i]); // fld.SetValue(cols[i], true); //} //return cols; return base.GetProperties(context, value, attributes); } } public class BaseCollectionConverter : BaseConverter { #region ExpandableCollectionPropertyDescriptor public class ExpandableCollectionPropertyDescriptor : PropertyDescriptor { private IList collection; private readonly int _index; public int Index { get { return _index; } } /// /// Initializes a new instance of the class. /// /// /// public ExpandableCollectionPropertyDescriptor(IList coll, int idx) : base("ExpandableCollectionPropertyDescriptor", null) { collection = coll; _index = idx; } public override string DisplayName => GetDisplayName(collection, _index); private static string GetDisplayName(IList list, int index) { return new StringBuilder() .Append('\t', list.Count - index) .AppendFormat("[{0}] {1}", index, CSharpName(list[index].GetType())) .ToString(); } private static string CSharpName(Type type) { var dnAttribute = type.GetCustomAttributes(typeof(DisplayNameAttribute), true) .FirstOrDefault() as DisplayNameAttribute; if (dnAttribute != null) { return dnAttribute.DisplayName; } var sb = new StringBuilder(); var name = type.Name; if (!type.IsGenericType) return name; sb.Append(name.Substring(0, name.IndexOf('`'))); sb.Append("<"); sb.Append(string.Join(", ", type.GetGenericArguments() .Select(CSharpName))); sb.Append(">"); return sb.ToString(); } public override bool CanResetValue(object component) { return true; } public override Type ComponentType { get { return this.collection.GetType(); } } public override object GetValue(object component) { return collection[_index]; } public override bool IsReadOnly { get { return false; } } public override string Name { get { return _index.ToString(CultureInfo.InvariantCulture); } } public override Type PropertyType { get { return collection[_index].GetType(); } } public override void ResetValue(object component) { } public override bool ShouldSerializeValue(object component) { return true; } public override void SetValue(object component, object value) { collection[_index] = value; } } #endregion public override bool GetPropertiesSupported(ITypeDescriptorContext context) { return true; } public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) { if (value is IList list && list.Count > 0) { var items = new PropertyDescriptorCollection(null); for (int i = 0; i < list.Count; i++) { object item = list[i]; ExpandableCollectionPropertyDescriptor desc = new ExpandableCollectionPropertyDescriptor(list, i); items.Add(desc); } return items.Sort(new DescComparer()); } return base.GetProperties(context, value, attributes); } public class DescComparer : IComparer { public int Compare(object x, object y) { // 这里是你的自定义排序逻辑 // 例如,我们可以按照属性名的长度进行排序 ExpandableCollectionPropertyDescriptor pdx = x as ExpandableCollectionPropertyDescriptor; ExpandableCollectionPropertyDescriptor pdy = y as ExpandableCollectionPropertyDescriptor; return pdx.Index.CompareTo(pdy.Index); } } } public class BaseDropDownConverter : BaseConverter { public override Boolean GetStandardValuesSupported(ITypeDescriptorContext context) { return true; } public override Boolean GetStandardValuesExclusive(ITypeDescriptorContext context) { return true; } } public abstract class EnumConverter : BaseDropDownConverter where T : struct, IConvertible //Enum { protected abstract Dictionary CreateMaps(); private volatile Dictionary maps; private volatile StandardValuesCollection values; private Dictionary GetMap() { if (maps == null) { maps = CreateMaps(); } return maps; } public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { return values ?? (values = new StandardValuesCollection(GetMap().Keys)); } public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { if (value != null && value is string) { foreach (var item in maps) { if (value.Equals(item.Value)) { if (context.PropertyDescriptor.PropertyType == typeof(int)) { return Convert.ToInt32(item.Key); } else { return item.Key; } } } } return base.ConvertFrom(context, culture, value); } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { return destinationType == typeof(string) || base.CanConvertTo(context, destinationType); } public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(string)) { if (value is int iValue) { var eValue = (T)Enum.ToObject(typeof(T), iValue); if (GetMap().ContainsKey(eValue)) { return GetMap()[eValue]; } } if (value is T tValue) { if (GetMap().ContainsKey(tValue)) { return GetMap()[tValue]; } } } return base.ConvertTo(context, culture, value, destinationType); } } }