WPF开发快速入门【6】下拉框与枚举类型

概述

本文讲述下拉框和枚举类型进行绑定的一些操作。

 

下拉框的基本操作

设计部分:

        <ComboBox ItemsSource="{Binding Fruits}"
                  SelectedItem="{Binding SelectedFruit}" 
                  SelectedIndex="{Binding SelectedIndex}"/>

代码部分:

        public List<string> Fruits { get; set; } = new List<string> { "Apple","Bonana", "Strawberry" };
        public string SelectedFruit { get; set; }
        public int SelectedIndex { get; set; }

以上是最简单的一种绑定形式,采用字符串列表作为数据源。虽然SelectedItem和SelectedIndex都可以用来控制或获取选择项,但建议还是使用SelectedItem比较合适,因为下拉框的数据是可以绑定任意对象列表的,通过SelectedItem就可以直接获取到对象。注意用于绑定的对象应重写ToString()方法。

 

下拉框绑定枚举类型

首先我们定义一个枚举类型 

    public enum AlarmLevel
    {       
        Normal = 0,      
        Warring = 1,      
        Error = 2,
    }

  然后定义要绑定的源:

        public List<AlarmLevel> Fruits { get; set; } = new List<AlarmLevel> { AlarmLevel.Normal, AlarmLevel.Warring, AlarmLevel.Error };
        public AlarmLevel SelectedFruit { get; set; }

 设计端代码:

        <ComboBox ItemsSource="{Binding Fruits}"
                  SelectedItem="{Binding SelectedFruit}"/>

 这样就实现绑定了。但初始化枚举对象列表的代码有点麻烦,我们需要优化一下。

新建一个辅助类

    public class EnumHelper<T>
    {
        public static List<T> ToList()
        {
            return Enum.GetValues(typeof(T)).Cast<T>().ToList();
        }
    }

 初始化代码就可以简化为下面形式:

public List<AlarmLevel> Fruits = EnumHelper<AlarmLevel>.ToList();

 这个代码对所有枚举类型都适用。 

 

下拉框中文字显示枚举的描述信息

有时候我们希望下拉框显示的内容和枚举项的定义名称并不一致,比如定义项为“Normal”,界面显示“正常”,这个要求也是可以实现的。下面代码实现界面显示枚举项的Description值。

定义枚举类对象,如下:

    public enum AlarmLevel
    {
        [Description("正常")]
        Normal = 0,

        [Description("警报")]
        Warring = 1,

        [Description("故障")]
        Error = 2,
    }

 ViewModel中代码不变,我们要增加一个转换器来实现这个功能

    public class EnumDescriptionConverter : IValueConverter
    {
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Enum myEnum = (Enum)value;
            string description = GetEnumDescription(myEnum);
            return description;
        }

        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return string.Empty;
        }

        private string GetEnumDescription(Enum enumObj)
        {
            FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());

            object[] attribArray = fieldInfo.GetCustomAttributes(false);

            if (attribArray.Length == 0)
            {
                return enumObj.ToString();
            }
            else
            {
                DescriptionAttribute attrib = attribArray[0] as DescriptionAttribute;
                return attrib.Description;
            }
        }
    }
View Code

 前端代码修改如下:

<UserControl x:Class="LearnWPF.Pages.PageComboBoxView"
             xmlns:util="clr-namespace:LearnWPF.Utils">
    
    <UserControl.Resources>
        <util:EnumDescriptionConverter x:Key="enumDescriptionConverter" />
    </UserControl.Resources>

    <Canvas>
        <ComboBox ItemsSource="{Binding AlarmLevelList}"
                  SelectedItem="{Binding SelectedAlarmLevel}">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Converter={StaticResource enumDescriptionConverter}}" />
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>      
    </Canvas>
</UserControl>

 这里稍微分析一下转换器。

这里的转换器必须继承于IValueConverter接口,它有Convert和ConvertBack两个方法。以Convert为例,其输入是一个object,来源是ItemTemplate模板的当前对象,输出也是一个对象,ItemTemplate会用输出的对象代替原来的对象。

自定义的输出的对象应重写ToString()方法。

以上转换器的设计是将枚举对象转换为其Description特性,实际应用时可能需要考虑国际化的需求,其转换数据的来源也不一定要从Description取值,完全可以根据需要另行设计。

 

资源

系列目录:WPF开发快速入门【0】前言与目录 

代码下载:Learn WPF: WPF学习笔记 (gitee.com)

posted @ 2022-08-23 16:43  seabluescn  阅读(1934)  评论(0编辑  收藏  举报