在WPF中绑定Enums数据
在我们使用WPF的时候,经常要进行数据绑定到Enum,在这里,我将展示在WPF中处理Enum数据绑定的方法
Enum
定义如下
[TypeConverter(typeof(EnumDescriptionTypeConverter))]
public enum Gender
{
[Description("女性")]
Woman,
[Description("男性")]
Man
}
public class EnumDescriptionTypeConverter : EnumConverter
{
public EnumDescriptionTypeConverter(Type type) : base(type)
{
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
if (value != null)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
if (fi != null)
{
var attribute = fi.GetCustomAttribute<DescriptionAttribute>();
return attribute?.Description;
}
}
return string.Empty;
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
-
使用
ObjectDataProvider
-
添加引用
在
xaml
文件中从mscorlib
中引入命名空间System
。xmlns:sys="clr-namespace:System;assembly=mscorlib"
-
创建一个
ObjectDataProvider
资源在此,你需要创建一个
ObjectDataProvider
资源,并给它一个键名DataFromGenderEnum
,这样就可以在代码中使用它<ObjectDataProvider x:Key="DataFromGenderEnum" MethodName="GetValues" ObjectType="{x:Type sys:Enum}"> <ObjectDataProvider.MethodParameters> <x:Type TypeName="local:Gender"></x:Type> </ObjectDataProvider.MethodParameters> </ObjectDataProvider>
-
Binding
数据处理现在,你可以使用数据绑定了
<ComboBox ItemsSource="{Binding Source={StaticResource DataFromGenderEnum}}"></ComboBox>
-
-
使用
MarkupExtension
帮助类在使用中我们会发现,使用方法1,你需要对不同的
Enum
创建不同的ObjectDataProvider
,在这里我们使用MarkupExtension
就只需要创建一个帮助类就可以支持多个Enum
-
我们先创建帮助类
EnumBindingSourceExtention
public class EnumBindingSourceExtention : MarkupExtension { private Type _enumType; public EnumBindingSourceExtention(Type enumType) { EnumType = enumType; } public EnumBindingSourceExtention() { } public Type EnumType { get { return _enumType; } set { if (_enumType != value) { if (value != null) { var enumType = Nullable.GetUnderlyingType(value) ?? value; if (!enumType.IsEnum) { throw new ArgumentException("必须是一个枚举类型"); } } _enumType = value; } } } public override object ProvideValue(IServiceProvider serviceProvider) { if (_enumType == null) { throw new InvalidOperationException("必须先指定EnumType"); } var actualEnumType = Nullable.GetUnderlyingType(_enumType) ?? _enumType; var enumValues = Enum.GetValues(actualEnumType); if (actualEnumType == _enumType) { return enumValues; } var tempArray = Array.CreateInstance(actualEnumType, enumValues.Length + 1); enumValues.CopyTo(tempArray, 1); return tempArray; } }
-
然后进行数据绑定
<ComboBox ItemsSource="{Binding Source={local:EnumBindingSourceExtention {x:Type local:Gender}}}" />
-