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

推荐订阅源

量子位
Stack Overflow Blog
Stack Overflow Blog
人人都是产品经理
人人都是产品经理
The GitHub Blog
The GitHub Blog
Engineering at Meta
Engineering at Meta
Vercel News
Vercel News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Y
Y Combinator Blog
The Cloudflare Blog
Last Week in AI
Last Week in AI
B
Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog
V
Visual Studio Blog
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
Google DeepMind News
Google DeepMind News
D
DataBreaches.Net
博客园 - 司徒正美
B
Blog RSS Feed
Microsoft Azure Blog
Microsoft Azure Blog
罗磊的独立博客
Hugging Face - Blog
Hugging Face - Blog
L
LangChain Blog

博客园 - 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)