在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);
    }
}
  1. 使用ObjectDataProvider

    1. 添加引用

      xaml文件中从mscorlib中引入命名空间System

      xmlns:sys="clr-namespace:System;assembly=mscorlib"
      
    2. 创建一个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>
      
    3. Binding数据处理

      现在,你可以使用数据绑定了

      <ComboBox ItemsSource="{Binding Source={StaticResource DataFromGenderEnum}}"></ComboBox>
      
  2. 使用MarkupExtension帮助类

    在使用中我们会发现,使用方法1,你需要对不同的Enum创建不同的ObjectDataProvider,在这里我们使用MarkupExtension就只需要创建一个帮助类就可以支持多个Enum

    1. 我们先创建帮助类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;
          }
      }
      
    2. 然后进行数据绑定

      <ComboBox ItemsSource="{Binding Source={local:EnumBindingSourceExtention {x:Type local:Gender}}}" />
posted @ 2021-10-28 17:08  追寻未来的笨鸟  阅读(283)  评论(0编辑  收藏  举报