不以物喜,不以己悲

学习WPF中绑定枚举的方式

学习WPF中绑定枚举的方式

最近看到一篇介绍WPF绑定枚举的好方法,查看地址:https://www.cnblogs.com/sesametech-netcore/p/13878443.html,这里记录一下。

假定现在有个枚举数据如下:

/// <summary>
/// 控制类型
/// </summary>
public enum CMDType
{
    [Description("Ai巡检")]
    Ai,
    [Description("心跳")]
    Keeplive,
    [Description("切源命令")]
    Stream_cmd,
    [Description("源状态")]
    Stream_state,
}

1、使用ObjectDataProvider

在xaml中引入命名空间System.

xmlns:sys="clr-namespace:System;assembly=mscorlib"

创建一个ObjectDataProvider资源,代码如下:

<Window.Resources>
        <ObjectDataProvider x:Key="DataEnum" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="local:CMDType" />
            </ObjectDataProvider.MethodParameters>
            
        </ObjectDataProvider>
    </Window.Resources>

那么现在就可以使用数据绑定了。例如绑定到ComboBox:

<ComboBox ItemsSource="{Binding Source={StaticResource DataEnum}}" />

2、使用MarkupExtension

 /// <summary>
    /// 绑定枚举
    /// </summary>
    public class EnumBindingSourceExtension : MarkupExtension
    {
        private Type enumType;
        public Type EnumType
        {
            get => this.enumType;
            set
            {
                if(value != this.enumType)
                {
                    if(value != null)
                    {
                        var enumType = Nullable.GetUnderlyingType(value) ?? value;
                        if (!enumType.IsEnum)
                        {
                            throw new ArgumentException("类型不是枚举");
                        }
                    }
                    this.enumType = value;
                }
            }
        }
        public EnumBindingSourceExtension()
        {

        }
        public EnumBindingSourceExtension(Type enumType)
        {
            this.EnumType = enumType;
        }
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if(this.enumType == null)
            {
                throw new InvalidOperationException("类型为空了");
            }
            var actualEnumType = Nullable.GetUnderlyingType(this.enumType) ?? this.enumType;
            var enumValues = Enum.GetValues(actualEnumType);
            if(actualEnumType == this.enumType)
            {
                return enumValues;
            }
            var tempArray = Array.CreateInstance(actualEnumType, enumValues.Length + 1);
            enumValues.CopyTo(tempArray, 1);
            return tempArray;
        }
    }

使用Description属性的值。

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)
                    {
                        DescriptionAttribute attributes = (DescriptionAttribute)fi.GetCustomAttribute(typeof(DescriptionAttribute), false);
                        return attributes?.Description;
                    }
                }
            }
            return string.Empty;
        }
    }
    [TypeConverter(typeof(EnumDescriptionTypeConverter))]
    /// <summary>
    /// 控制类型
    /// </summary>
    public enum CMDType
    {
        [Description("Ai巡检")]
        Ai,
        [Description("心跳")]
        Keeplive,
        [Description("切源命令")]
        Stream_cmd,
        [Description("源状态")]
        Stream_state,
    }
posted @ 2020-10-31 16:15  这种人  阅读(2317)  评论(0编辑  收藏  举报