From c259b7943daf1b7d6a091141a0925d96becefd29 Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Tue, 16 Jun 2020 00:35:37 +0800 Subject: [PATCH] use PropertyDescriptor --- .../HandyControl_Net_GE45.csproj | 3 - .../Editors/EnumPropertyEditor.cs | 22 +++++ .../Editors/PropertyEditorBase.cs | 8 +- .../Controls/PropertyGrid/PropertyGrid.cs | 25 +++--- .../Controls/PropertyGrid/PropertyItem.cs | 21 ++--- .../Controls/PropertyGrid/PropertyResolver.cs | 89 +++++-------------- .../HandyControl_Shared.projitems | 2 +- .../Extension/CustomAttributeExtension.cs | 12 --- 8 files changed, 71 insertions(+), 111 deletions(-) create mode 100644 src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/EnumPropertyEditor.cs delete mode 100644 src/Shared/HandyControl_Shared/Tools/Extension/CustomAttributeExtension.cs diff --git a/src/Net_GE45/HandyControl_Net_GE45/HandyControl_Net_GE45.csproj b/src/Net_GE45/HandyControl_Net_GE45/HandyControl_Net_GE45.csproj index 3d75fe2c..936ec214 100644 --- a/src/Net_GE45/HandyControl_Net_GE45/HandyControl_Net_GE45.csproj +++ b/src/Net_GE45/HandyControl_Net_GE45/HandyControl_Net_GE45.csproj @@ -134,7 +134,4 @@ Resources\Images\GlowWindow\topright.png - - - \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/EnumPropertyEditor.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/EnumPropertyEditor.cs new file mode 100644 index 00000000..8d5e908f --- /dev/null +++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/EnumPropertyEditor.cs @@ -0,0 +1,22 @@ +using System; +using System.Windows; +using System.Windows.Controls.Primitives; + +namespace HandyControl.Controls +{ + public class EnumPropertyEditor : PropertyEditorBase + { + public override FrameworkElement CreateElement(PropertyItem propertyItem) + { + var picker = new System.Windows.Controls.ComboBox + { + IsEnabled = !propertyItem.IsReadOnly, + ItemsSource = Enum.GetValues(propertyItem.PropertyType) + }; + + picker.SetBinding(Selector.SelectedValueProperty, CreateBinding(propertyItem)); + + return picker; + } + } +} \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/PropertyEditorBase.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/PropertyEditorBase.cs index bda2df14..1f1ccb5f 100644 --- a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/PropertyEditorBase.cs +++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/Editors/PropertyEditorBase.cs @@ -11,12 +11,12 @@ namespace HandyControl.Controls new Binding(propertyItem.PropertyName) { Source = propertyItem.Value, - Mode = GetBindingMode(), - UpdateSourceTrigger = GetUpdateSourceTrigger() + Mode = GetBindingMode(propertyItem), + UpdateSourceTrigger = GetUpdateSourceTrigger(propertyItem) }; - public virtual BindingMode GetBindingMode() => BindingMode.OneWay; + public virtual BindingMode GetBindingMode(PropertyItem propertyItem) => propertyItem.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay; - public virtual UpdateSourceTrigger GetUpdateSourceTrigger() => UpdateSourceTrigger.Default; + public virtual UpdateSourceTrigger GetUpdateSourceTrigger(PropertyItem propertyItem) => UpdateSourceTrigger.PropertyChanged; } } \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyGrid.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyGrid.cs index df67f1a5..37a5a2c6 100644 --- a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyGrid.cs +++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyGrid.cs @@ -1,7 +1,6 @@ using System; using System.ComponentModel; using System.Linq; -using System.Reflection; using System.Windows; using System.Windows.Controls; using System.Windows.Data; @@ -118,8 +117,8 @@ namespace HandyControl.Controls { if (obj == null || _itemsControl == null) return; - _dataView = CollectionViewSource.GetDefaultView(obj.GetType().GetProperties() - .Where(item => PropertyResolver.ResolveBrowsable(item)).Select(CreatePropertyItem) + _dataView = CollectionViewSource.GetDefaultView(TypeDescriptor.GetProperties(obj).OfType() + .Where(item => PropertyResolver.ResolveIsBrowsable(item)).Select(CreatePropertyItem) .Do(item => item.InitElement())); SortByCategory(null, null); @@ -167,18 +166,18 @@ namespace HandyControl.Controls } } - protected virtual PropertyItem CreatePropertyItem(PropertyInfo propertyInfo) => new PropertyItem + protected virtual PropertyItem CreatePropertyItem(PropertyDescriptor propertyDescriptor) => new PropertyItem { - Category = PropertyResolver.ResolveCategory(propertyInfo), - DisplayName = PropertyResolver.ResolveDisplayName(propertyInfo), - Description = PropertyResolver.ResolveDescription(propertyInfo), - IsReadOnly = PropertyResolver.ResolveIsReadOnly(propertyInfo), - DefaultValue = PropertyResolver.ResolveDefaultValue(propertyInfo), - Editor = PropertyResolver.ResolveEditor(propertyInfo), - Converter = PropertyResolver.ResolveConverter(propertyInfo), + Category = PropertyResolver.ResolveCategory(propertyDescriptor), + DisplayName = PropertyResolver.ResolveDisplayName(propertyDescriptor), + Description = PropertyResolver.ResolveDescription(propertyDescriptor), + IsReadOnly = PropertyResolver.ResolveIsReadOnly(propertyDescriptor), + DefaultValue = PropertyResolver.ResolveDefaultValue(propertyDescriptor), + Editor = PropertyResolver.ResolveEditor(propertyDescriptor), Value = SelectedObject, - PropertyName = propertyInfo.Name, - PropertyTypeName = propertyInfo.PropertyType.FullName + PropertyName = propertyDescriptor.Name, + PropertyType = propertyDescriptor.PropertyType, + PropertyTypeName = $"{propertyDescriptor.PropertyType.Namespace}.{propertyDescriptor.PropertyType.Name}" }; protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyItem.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyItem.cs index 77d2075d..fda7644b 100644 --- a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyItem.cs +++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyItem.cs @@ -1,4 +1,5 @@ -using System.Windows; +using System; +using System.Windows; using System.Windows.Controls; using System.Windows.Data; @@ -33,6 +34,15 @@ namespace HandyControl.Controls set => SetValue(PropertyNameProperty, value); } + public static readonly DependencyProperty PropertyTypeProperty = DependencyProperty.Register( + "PropertyType", typeof(Type), typeof(PropertyItem), new PropertyMetadata(default(Type))); + + public Type PropertyType + { + get => (Type) GetValue(PropertyTypeProperty); + set => SetValue(PropertyTypeProperty, value); + } + public static readonly DependencyProperty PropertyTypeNameProperty = DependencyProperty.Register( "PropertyTypeName", typeof(string), typeof(PropertyItem), new PropertyMetadata(default(string))); @@ -114,15 +124,6 @@ namespace HandyControl.Controls set => SetValue(IsExpandedEnabledProperty, value); } - public static readonly DependencyProperty ConverterProperty = DependencyProperty.Register( - "Converter", typeof(IValueConverter), typeof(PropertyItem), new PropertyMetadata(default(IValueConverter))); - - public IValueConverter Converter - { - get => (IValueConverter) GetValue(ConverterProperty); - set => SetValue(ConverterProperty, value); - } - public virtual void InitElement() { if (Editor == null) return; diff --git a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyResolver.cs b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyResolver.cs index baceed87..48d76b27 100644 --- a/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyResolver.cs +++ b/src/Shared/HandyControl_Shared/Controls/PropertyGrid/PropertyResolver.cs @@ -1,12 +1,8 @@ using System; using System.Collections.Generic; using System.ComponentModel; -using System.Reflection; -using System.Windows.Data; +using System.Linq; using HandyControl.Properties.Langs; -#if NET40 -using HandyControl.Tools.Extension; -#endif namespace HandyControl.Controls { @@ -29,15 +25,10 @@ namespace HandyControl.Controls [typeof(DateTime)] = EditorTypeCode.DateTime }; - public string ResolveCategory(PropertyInfo propertyInfo) + public string ResolveCategory(PropertyDescriptor propertyDescriptor) { - var categoryAttribute = propertyInfo.GetCustomAttribute(); - string category; - if (categoryAttribute != null && !string.IsNullOrEmpty(categoryAttribute.Category)) - { - category = categoryAttribute.Category; - } - else + var category = propertyDescriptor.Category; + if (string.IsNullOrEmpty(category)) { category = Lang.Miscellaneous; } @@ -45,74 +36,34 @@ namespace HandyControl.Controls return category; } - public string ResolveDisplayName(PropertyInfo propertyInfo) + public string ResolveDisplayName(PropertyDescriptor propertyDescriptor) { - var displayNameAttribute = propertyInfo.GetCustomAttribute(); - string displayName; - if (displayNameAttribute != null && !string.IsNullOrEmpty(displayNameAttribute.DisplayName)) + var displayName = propertyDescriptor.DisplayName; + if (string.IsNullOrEmpty(displayName)) { - displayName = displayNameAttribute.DisplayName; - } - else - { - displayName = propertyInfo.Name; + displayName = propertyDescriptor.Name; } return displayName; } - public string ResolveDescription(PropertyInfo propertyInfo) - { - var descriptionAttribute = propertyInfo.GetCustomAttribute(); - string description; - if (descriptionAttribute != null && !string.IsNullOrEmpty(descriptionAttribute.Description)) - { - description = descriptionAttribute.Description; - } - else - { - description = string.Empty; - } + public string ResolveDescription(PropertyDescriptor propertyDescriptor) => propertyDescriptor.Description; - return description; - } + public bool ResolveIsBrowsable(PropertyDescriptor propertyDescriptor) => propertyDescriptor.IsBrowsable; - public bool ResolveBrowsable(PropertyInfo propertyInfo) - { - var browsableAttribute = propertyInfo.GetCustomAttribute(); - return browsableAttribute == null || browsableAttribute.Browsable; - } + public bool ResolveIsReadOnly(PropertyDescriptor propertyDescriptor) => propertyDescriptor.IsReadOnly; - public bool ResolveIsReadOnly(PropertyInfo propertyInfo) + public object ResolveDefaultValue(PropertyDescriptor propertyDescriptor) { - var isReadOnlyAttribute = propertyInfo.GetCustomAttribute(); - return isReadOnlyAttribute != null && isReadOnlyAttribute.IsReadOnly; - } - - public object ResolveDefaultValue(PropertyInfo propertyInfo) - { - var defaultValueAttribute = propertyInfo.GetCustomAttribute(); + var defaultValueAttribute = propertyDescriptor.Attributes.OfType().FirstOrDefault(); return defaultValueAttribute?.Value; } - public IValueConverter ResolveConverter(PropertyInfo propertyInfo) + public PropertyEditorBase ResolveEditor(PropertyDescriptor propertyDescriptor) { - var typeConverterAttribute = propertyInfo.GetCustomAttribute(); - if (typeConverterAttribute != null && !string.IsNullOrEmpty(typeConverterAttribute.ConverterTypeName)) - { - return CreateTypeConverter(Type.GetType(typeConverterAttribute.ConverterTypeName)); - } - - return null; - } - - public virtual IValueConverter CreateTypeConverter(Type type) => Activator.CreateInstance(type) as IValueConverter; - - public PropertyEditorBase ResolveEditor(PropertyInfo propertyInfo) - { - var editorAttribute = propertyInfo.GetCustomAttribute(); + var editorAttribute = propertyDescriptor.Attributes.OfType().FirstOrDefault(); var editor = editorAttribute == null || string.IsNullOrEmpty(editorAttribute.EditorTypeName) - ? CreateDefaultEditor(propertyInfo.PropertyType) + ? CreateDefaultEditor(propertyDescriptor.PropertyType) : CreateEditor(Type.GetType(editorAttribute.EditorTypeName)); return editor; @@ -120,7 +71,7 @@ namespace HandyControl.Controls public virtual PropertyEditorBase CreateDefaultEditor(Type type) => TypeCodeDic.TryGetValue(type, out var editorType) - ? (PropertyEditorBase) (editorType switch + ? editorType switch { EditorTypeCode.PlainText => new PlainTextPropertyEditor(), EditorTypeCode.SByteNumber => new NumberPropertyEditor(sbyte.MinValue, sbyte.MaxValue), @@ -136,8 +87,10 @@ namespace HandyControl.Controls EditorTypeCode.Switch => new SwitchPropertyEditor(), EditorTypeCode.DateTime => new DateTimePropertyEditor(), _ => new PlainTextPropertyEditor() - }) - : new PlainTextPropertyEditor(); + } + : type.IsSubclassOf(typeof(Enum)) + ? (PropertyEditorBase) new EnumPropertyEditor() + : new PlainTextPropertyEditor(); public virtual PropertyEditorBase CreateEditor(Type type) => new PlainTextPropertyEditor(); diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems index d4698ad5..efd39a69 100644 --- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems +++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems @@ -40,6 +40,7 @@ + @@ -110,7 +111,6 @@ - diff --git a/src/Shared/HandyControl_Shared/Tools/Extension/CustomAttributeExtension.cs b/src/Shared/HandyControl_Shared/Tools/Extension/CustomAttributeExtension.cs deleted file mode 100644 index f50c4d9e..00000000 --- a/src/Shared/HandyControl_Shared/Tools/Extension/CustomAttributeExtension.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Reflection; - -namespace HandyControl.Tools.Extension -{ - internal static class CustomAttributeExtension - { - public static Attribute GetCustomAttribute(this MemberInfo element, Type attributeType) => Attribute.GetCustomAttribute(element, attributeType); - - public static T GetCustomAttribute(this MemberInfo element) where T : Attribute => (T)GetCustomAttribute(element, typeof(T)); - } -} \ No newline at end of file