use PropertyDescriptor

This commit is contained in:
NaBian committed 2020-06-16 00:35:37 +08:00
1 parent f7a39f3d32
commit c259b7943d
8 files changed
+71 -111

No files matched your search

@@ -134,7 +134,4 @@
<Link>Resources\Images\GlowWindow\topright.png</Link>
</Resource>
</ItemGroup>
<ItemGroup>
<None Remove="..\..\Shared\HandyControl_Shared\Tools\Extension\CustomAttributeExtension.cs" />
</ItemGroup>
</Project>
@@ -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;
}
}
}
@@ -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;
}
}
@@ -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<PropertyDescriptor>()
.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)
@@ -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;
@@ -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<CategoryAttribute>();
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<DisplayNameAttribute>();
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<DescriptionAttribute>();
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<BrowsableAttribute>();
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<ReadOnlyAttribute>();
return isReadOnlyAttribute != null && isReadOnlyAttribute.IsReadOnly;
}
public object ResolveDefaultValue(PropertyInfo propertyInfo)
{
var defaultValueAttribute = propertyInfo.GetCustomAttribute<DefaultValueAttribute>();
var defaultValueAttribute = propertyDescriptor.Attributes.OfType<DefaultValueAttribute>().FirstOrDefault();
return defaultValueAttribute?.Value;
}
public IValueConverter ResolveConverter(PropertyInfo propertyInfo)
public PropertyEditorBase ResolveEditor(PropertyDescriptor propertyDescriptor)
{
var typeConverterAttribute = propertyInfo.GetCustomAttribute<TypeConverterAttribute>();
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<EditorAttribute>();
var editorAttribute = propertyDescriptor.Attributes.OfType<EditorAttribute>().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();
@@ -40,6 +40,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Notification.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Poptip.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Watermark.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\Editors\EnumPropertyEditor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\Editors\TimePropertyEditor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\Editors\DatePropertyEditor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\PropertyGrid\Editors\SwitchPropertyEditor.cs" />
@@ -110,7 +111,6 @@
<Compile Include="$(MSBuildThisFileDirectory)Tools\Converter\Number2PercentageConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Converter\RectangleCircularConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Converter\ThicknessSplitConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Extension\CustomAttributeExtension.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Extension\DependencyObjectExtension.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Extension\FrameworkElementExtension.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Extension\LangExtension.cs" />
@@ -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<T>(this MemberInfo element) where T : Attribute => (T)GetCustomAttribute(element, typeof(T));
}
}