|
|
|
|
|
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<T> : 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<TypeConverter>
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class BaseExpandableConverter : BaseConverter<ExpandableObjectConverter>
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
public class BaseExpandableReadonlyConverter : BaseConverter<ExpandableObjectConverter>
|
|
|
|
|
|
{
|
|
|
|
|
|
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<CollectionConverter>
|
|
|
|
|
|
{
|
|
|
|
|
|
#region ExpandableCollectionPropertyDescriptor
|
|
|
|
|
|
public class ExpandableCollectionPropertyDescriptor : PropertyDescriptor
|
|
|
|
|
|
{
|
|
|
|
|
|
private IList collection;
|
|
|
|
|
|
private readonly int _index;
|
|
|
|
|
|
public int Index { get { return _index; } }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Initializes a new instance of the <see cref="ExpandableCollectionPropertyDescriptor"/> class.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="coll"></param>
|
|
|
|
|
|
/// <param name="idx"></param>
|
|
|
|
|
|
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<TypeConverter>
|
|
|
|
|
|
{
|
|
|
|
|
|
public override Boolean GetStandardValuesSupported(ITypeDescriptorContext context) { return true; }
|
|
|
|
|
|
public override Boolean GetStandardValuesExclusive(ITypeDescriptorContext context) { return true; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public abstract class EnumConverter<T> : BaseDropDownConverter
|
|
|
|
|
|
where T : struct, IConvertible //Enum
|
|
|
|
|
|
{
|
|
|
|
|
|
protected abstract Dictionary<T, string> CreateMaps();
|
|
|
|
|
|
|
|
|
|
|
|
private volatile Dictionary<T, string> maps;
|
|
|
|
|
|
private volatile StandardValuesCollection values;
|
|
|
|
|
|
|
|
|
|
|
|
private Dictionary<T, string> 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);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|