using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Windows; using System.Windows.Media; using HandyControl.Properties.Langs; namespace HandyControl.Controls; public class PropertyResolver { private static readonly Dictionary TypeCodeDic = new() { [typeof(string)] = EditorTypeCode.PlainText, [typeof(sbyte)] = EditorTypeCode.SByteNumber, [typeof(byte)] = EditorTypeCode.ByteNumber, [typeof(short)] = EditorTypeCode.Int16Number, [typeof(ushort)] = EditorTypeCode.UInt16Number, [typeof(int)] = EditorTypeCode.Int32Number, [typeof(uint)] = EditorTypeCode.UInt32Number, [typeof(long)] = EditorTypeCode.Int64Number, [typeof(ulong)] = EditorTypeCode.UInt64Number, [typeof(float)] = EditorTypeCode.SingleNumber, [typeof(double)] = EditorTypeCode.DoubleNumber, [typeof(bool)] = EditorTypeCode.Switch, [typeof(DateTime)] = EditorTypeCode.DateTime, [typeof(HorizontalAlignment)] = EditorTypeCode.HorizontalAlignment, [typeof(VerticalAlignment)] = EditorTypeCode.VerticalAlignment, [typeof(ImageSource)] = EditorTypeCode.ImageSource }; public string ResolveCategory(PropertyDescriptor propertyDescriptor) { var categoryAttribute = propertyDescriptor.Attributes.OfType().FirstOrDefault(); return categoryAttribute == null ? Lang.Miscellaneous : string.IsNullOrEmpty(categoryAttribute.Category) ? Lang.Miscellaneous : categoryAttribute.Category; } public string ResolveDisplayName(PropertyDescriptor propertyDescriptor) { var displayName = propertyDescriptor.DisplayName; if (string.IsNullOrEmpty(displayName)) { displayName = propertyDescriptor.Name; } return displayName; } public string ResolveDescription(PropertyDescriptor propertyDescriptor) => propertyDescriptor.Description; public bool ResolveIsBrowsable(PropertyDescriptor propertyDescriptor) => propertyDescriptor.IsBrowsable; public bool ResolveIsDisplay(PropertyDescriptor propertyDescriptor) => propertyDescriptor.IsLocalizable; public bool ResolveIsReadOnly(PropertyDescriptor propertyDescriptor) => propertyDescriptor.IsReadOnly; public object ResolveDefaultValue(PropertyDescriptor propertyDescriptor) { var defaultValueAttribute = propertyDescriptor.Attributes.OfType().FirstOrDefault(); return defaultValueAttribute?.Value; } public PropertyEditorBase ResolveEditor(PropertyDescriptor propertyDescriptor) { var editorAttribute = propertyDescriptor.Attributes.OfType().FirstOrDefault(); var editor = editorAttribute == null || string.IsNullOrEmpty(editorAttribute.EditorTypeName) ? CreateDefaultEditor(propertyDescriptor.PropertyType) : CreateEditor(Type.GetType(editorAttribute.EditorTypeName)); return editor; } public virtual PropertyEditorBase CreateDefaultEditor(Type type) => TypeCodeDic.TryGetValue(type, out var editorType) ? editorType switch { EditorTypeCode.PlainText => new PlainTextPropertyEditor(), EditorTypeCode.SByteNumber => new NumberPropertyEditor(sbyte.MinValue, sbyte.MaxValue), EditorTypeCode.ByteNumber => new NumberPropertyEditor(byte.MinValue, byte.MaxValue), EditorTypeCode.Int16Number => new NumberPropertyEditor(short.MinValue, short.MaxValue), EditorTypeCode.UInt16Number => new NumberPropertyEditor(ushort.MinValue, ushort.MaxValue), EditorTypeCode.Int32Number => new NumberPropertyEditor(int.MinValue, int.MaxValue), EditorTypeCode.UInt32Number => new NumberPropertyEditor(uint.MinValue, uint.MaxValue), EditorTypeCode.Int64Number => new NumberPropertyEditor(long.MinValue, long.MaxValue), EditorTypeCode.UInt64Number => new NumberPropertyEditor(ulong.MinValue, ulong.MaxValue), EditorTypeCode.SingleNumber => new NumberPropertyEditor(float.MinValue, float.MaxValue), EditorTypeCode.DoubleNumber => new NumberPropertyEditor(double.MinValue, double.MaxValue), EditorTypeCode.Switch => new SwitchPropertyEditor(), EditorTypeCode.DateTime => new DateTimePropertyEditor(), EditorTypeCode.HorizontalAlignment => new HorizontalAlignmentPropertyEditor(), EditorTypeCode.VerticalAlignment => new VerticalAlignmentPropertyEditor(), EditorTypeCode.ImageSource => new ImagePropertyEditor(), _ => new ReadOnlyTextPropertyEditor() } : type.IsSubclassOf(typeof(Enum)) ? new EnumPropertyEditor() : new ReadOnlyTextPropertyEditor(); public virtual PropertyEditorBase CreateEditor(Type type) => Activator.CreateInstance(type) as PropertyEditorBase ?? new ReadOnlyTextPropertyEditor(); private enum EditorTypeCode { PlainText, SByteNumber, ByteNumber, Int16Number, UInt16Number, Int32Number, UInt32Number, Int64Number, UInt64Number, SingleNumber, DoubleNumber, Switch, DateTime, HorizontalAlignment, VerticalAlignment, ImageSource } }