using System.ComponentModel; using System.Reflection; using System.Windows; using System.Windows.Controls.Primitives; using System.Windows.Markup; namespace ShrlAlgoToolkit.Mvvm.Markup { /// /// 枚举类作为数据源 /// 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; } } } /// /// 在ResouceDictionary中声明 /// /// local:EnumSourceExtension x:Key="EnumBindingSource" EnumType="{x:Type local:Sex}" /// ItemsSource="{local:EnumSource EnumType=local:ExampleEnum}" SelectedItem="{Binding ExampleEnum}" public EnumSourceExtension() { } /// /// 用Markup语法 /// /// /// 若需要绑定Description,则需设置BindToDescription为True,同时只能用SelectedValue来绑定源属性 /// ItemsSource="{Binding Source={local:EnumTypeBindingSource {x:Type local:ExampleEnum}}}" 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(); 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(); return descriptionAttribute?.Description ?? enumValue.ToString(); } } }