惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
罗磊的独立博客
小众软件
小众软件
T
Tailwind CSS Blog
宝玉的分享
宝玉的分享
博客园_首页
N
Netflix TechBlog - Medium
B
Blog
Recent Announcements
Recent Announcements
Y
Y Combinator Blog
Blog — PlanetScale
Blog — PlanetScale
L
LangChain Blog
F
Fortinet All Blogs
The GitHub Blog
The GitHub Blog
Stack Overflow Blog
Stack Overflow Blog
C
Check Point Blog
Last Week in AI
Last Week in AI
Jina AI
Jina AI
V
V2EX
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 叶小钗
博客园 - 【当耐特】

博客园 - seabluescn

WPF开发快速入门【8】WPF进行简单的3D开发 WPF开发快速入门【7】WPF的拖放功能(Drag and Drop) WPF开发快速入门【5】DataGrid的使用 WPF开发快速入门【4】自定义控件与用户控件 WPF开发快速入门【3】WPF的基本特性(附加属性) WPF开发快速入门【2】WPF的基本特性(Style、Trigger、Template) WPF开发快速入门【1】WPF的布局 WPF开发快速入门【0】前言与目录 WPF优秀组件推荐之FreeSpire WPF优秀组件推荐之LiveCharts WPF优秀组件推荐之MahApps WPF优秀组件推荐之Stylet(二) WPF优秀组件推荐之Stylet(一) TensorFlow.NET机器学习入门【9】后记 TensorFlow.NET机器学习入门【8】采用GPU进行学习 TensorFlow.NET机器学习入门【7】采用卷积神经网络(CNN)处理Fashion-MNIST TensorFlow.NET机器学习入门【6】采用神经网络处理Fashion-MNIST TensorFlow.NET机器学习入门【5】采用神经网络实现手写数字识别(MNIST) TensorFlow.NET机器学习入门【4】采用神经网络处理分类问题
WPF开发快速入门【6】下拉框与枚举类型
seabluescn · 2022-08-23 · via 博客园 - seabluescn

概述

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

下拉框的基本操作

设计部分:

        <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)