2025-02-10 20:53:40 +08:00
|
|
|
|
using System.ComponentModel;
|
2024-09-22 11:05:41 +08:00
|
|
|
|
using System.Reflection;
|
|
|
|
|
|
using System.Windows;
|
|
|
|
|
|
using System.Windows.Controls.Primitives;
|
|
|
|
|
|
using System.Windows.Markup;
|
|
|
|
|
|
|
2025-02-10 20:53:40 +08:00
|
|
|
|
namespace ShrlAlgo.Toolkit.Mvvm.Markup
|
2024-09-22 11:05:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 枚举类作为数据源
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class EnumSourceExtension : MarkupExtension
|
|
|
|
|
|
{
|
|
|
|
|
|
private Type enumType;
|
|
|
|
|
|
public bool BindToDescription { get; set; } = false;
|
|
|
|
|
|
public Type EnumType
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return enumType; }
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
if (value != enumType)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (null != value)
|
|
|
|
|
|
{
|
|
|
|
|
|
var enumType = Nullable.GetUnderlyingType(value) ?? value;
|
|
|
|
|
|
if (!enumType.IsEnum)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new ArgumentException("类型必须是枚举类型");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
enumType = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 在ResouceDictionary中声明
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <example><c>local:EnumSourceExtension x:Key="EnumBindingSource" EnumType="{x:Type local:Sex}"</c></example>
|
|
|
|
|
|
public EnumSourceExtension()
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 用Markup语法
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="enumType"></param>
|
|
|
|
|
|
/// <remarks>若需要绑定Description,则需设置BindToDescription为True,同时只能用SelectedValue来绑定源属性</remarks>
|
|
|
|
|
|
/// <example><c>ItemsSource="{Binding Source={local:EnumTypeBindingSource {x:Type local:ExampleEnum}}}"</c></example>
|
|
|
|
|
|
/// <example><c>ItemsSource="{local:EnumSource EnumType=local:ExampleEnum}" SelectedItem="{Binding ExampleEnum}"</c></example>
|
|
|
|
|
|
public EnumSourceExtension(Type enumType) { EnumType = enumType; }
|
|
|
|
|
|
|
|
|
|
|
|
public override object ProvideValue(IServiceProvider serviceProvider)
|
|
|
|
|
|
{
|
|
|
|
|
|
var pvt = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
|
|
|
|
|
|
|
|
|
|
|
|
if (pvt == null) { return null; }
|
|
|
|
|
|
|
|
|
|
|
|
//如果为空,则返回运行时绑定的类。
|
|
|
|
|
|
if (pvt.TargetObject is not FrameworkElement) { return this; }
|
|
|
|
|
|
|
|
|
|
|
|
var enumValues = Enum.GetValues(enumType);
|
|
|
|
|
|
if (BindToDescription)
|
|
|
|
|
|
{
|
|
|
|
|
|
var items = new List<object>();
|
|
|
|
|
|
foreach (var enumValue in enumValues)
|
|
|
|
|
|
{
|
|
|
|
|
|
var item = new
|
|
|
|
|
|
{
|
|
|
|
|
|
Value = enumValue,
|
|
|
|
|
|
Description = GetDescription(enumValue)
|
|
|
|
|
|
};
|
|
|
|
|
|
items.Add(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (pvt.TargetObject is Selector selector)
|
|
|
|
|
|
{
|
|
|
|
|
|
selector.DisplayMemberPath = "Description";
|
|
|
|
|
|
selector.SelectedValuePath = "Value";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return items;
|
|
|
|
|
|
}
|
|
|
|
|
|
return enumValues;
|
|
|
|
|
|
}
|
|
|
|
|
|
private static string GetDescription(object enumValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
var fieldInfo = enumValue.GetType().GetField(enumValue.ToString());
|
|
|
|
|
|
var descriptionAttribute = fieldInfo.GetCustomAttribute<DescriptionAttribute>();
|
|
|
|
|
|
|
|
|
|
|
|
return descriptionAttribute?.Description ?? enumValue.ToString();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|