引言

在你使用wpf应用程序开发的时候,是否需要进行数据绑定到Enum数据呢?在这篇文章中,我将向你展示在WPF中处理Enum数据绑定的方法。

假设存在一个这样的Enum数据的定义,具体内容如下文代码中所示:

namespace LocalizeFrameworkWpfApp
{public enum Status{Horrible,Bad,SoSo,Good,Better,Best}
}

一、WPF中的通常处理方法

1.1 添加引用

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

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

1.2 创建一个ObjectDataProvider资源

在此步骤中,你需要创建一个ObjectDataProvider的资源,并给它一个键名x:Key="DataFromEnum",这样就可以使用DataFromEnum在代码中使用它。并且你需要给MethodName设置为Enum类型上存在的GetValues,然后将ObjectType设置为Enum类型。接下来,你将需设置ObjectDataProvider.MethodParametersEnum类型。最后,你添加的ObjectDataProvider资源如下面代码所示

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

1.3 Binding数据处理

现在,你可以使用数据绑定了。例如,想将数据绑定到ComboBox上面,那么你需要设置ItemSource为一个新的绑定,并将数据源绑定到我们上面定义的名为DataFromEnum的资源。

    <Grid><ComboBoxMinWidth="150"HorizontalAlignment="Center"VerticalAlignment="Center"ItemsSource="{Binding Source={StaticResource DataFromEnum}}"></ComboBox></Grid>

到现在为止,所有的已经处理完成,运行程序可以看到数据已经正确绑定到ComboBox上面。

二、较好的处理方法

让我们来看看当数据绑定Enum类型时,如何使用WPF特性来改进代码的使用和可读性。首先,想封装Enum类型的绑定而不需要ObjectDataProvider资源的逻辑处理,还希望不需要必须定义资源才能在xaml中使用绑定功能。理想情况下,应该像处理普通对象的绑定一样,将所有内容都内联处理。为此,需要利用定制MarkupExtension的帮助类。这个扩展将简单的接受Enum类型,然后为控件创建一个可绑定Enum值的列表,这种实现其实很简单。

2.1 MarkupExtension帮助类

MarkupExtension帮助类定义如下:

namespace LocalizeFrameworkWpfApp
{public class EnumBindingSourceExtension:MarkupExtension{private Type _enumType;public Type EnumType{get { return _enumType; }set{if (value != _enumType){if (null != value){var enumType = Nullable.GetUnderlyingType(value) ?? value;if (!enumType.IsEnum){throw new ArgumentException("Type must bu for an Enum");}}_enumType = value;}}}public EnumBindingSourceExtension(){}public EnumBindingSourceExtension(Type enumType){EnumType = enumType;}public override object ProvideValue(IServiceProvider serviceProvider){if (null == _enumType){throw  new InvalidOperationException("The EnumTYpe must be specified.");}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.2 Binding数据处理

    <Grid><StackPanel><ComboBoxMinWidth="150"HorizontalAlignment="Center"ItemsSource="{Binding Source={StaticResource DataFromEnum}}"></ComboBox><ComboBoxMinWidth="150"HorizontalAlignment="Center"ItemsSource="{Binding Source={local:EnumBindingSource {x:Type local:Status}}}"></ComboBox></StackPanel></Grid>

看一下运行结果:

三、扩展:添加Enum类型的描述(Description)支持

现在我们可以不用使用ObjectDataProvider资源进行Enum类型的绑定工作了。这两种方法进行对比一下,详细这个新方法会让你耳目一新,像发现了新大陆一般。

Enum类型的值一般使用在程序中,而为了让用户获得更好的使用体验,一般都会在枚举值前面添加上属性:Description描述。为了完成此工作,我们只需使用TypeConverter进行转换。

namespace LocalizeFrameworkWpfApp
{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 (null != value){FieldInfo fi = value.GetType().GetField(value.ToString());if (null != fi){var attributes =(DescriptionAttribute[]) fi.GetCustomAttributes(typeof(DescriptionAttribute), false);return ((attributes.Length > 0) && (!string.IsNullOrEmpty(attributes[0].Description)))? attributes[0].Description: value.ToString();}}return string.Empty;}return base.ConvertTo(context, culture, value, destinationType);}}
}

然后对定义的枚举值添加上[Description]属性

namespace LocalizeFrameworkWpfApp
{[TypeConverter(typeof(EnumDescriptionTypeConverter))]public enum Status{[Description("This is horrible")]Horrible,[Description("This is Bad")]Bad,[Description("This is SoSo")]SoSo,[Description("This is Good")]Good,[Description("This is Better")]Better,[Description("This is Best")]Best}
}

程序运行结果:

可以看到,我们添加了[Description]属性时,这两种方法都可以将[Description]属性的值绑定到指定控件中。

运行wpf_在WPF中一种较好的绑定Enums数据方法相关推荐

  1. WPF中如何将ListViewItem双击事件绑定到Command

    原文:WPF中如何将ListViewItem双击事件绑定到Command 今天的博客将介绍如何实现ListViewItem双击事件绑定到ViewModel中的Command.实现方法借助了Style中 ...

  2. 【面试题】CSS 中几种最常用的水平垂直居中的方法

    目录 CSS 中几种最常用的水平垂直居中的方法 一.使用 margin:auto 二.使用 position:absolute 三.使用弹性布局 四.文本水平对齐和行高 五.使用网格布局 CSS 中几 ...

  3. python numpy读取数据_numpy中以文本的方式存储以及读取数据方法

    这篇文章主要介绍了关于numpy中以文本的方式存储以及读取数据方法,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 Numpy中除了能够把数据以二进制文件的方式保存到文件中以外,还可以选 ...

  4. WPF中5种内建面板Canvas、StackPanel、WrapPanel、DockPanel、Grid分析

    Canvas.StackPanel.WrapPanel.DockPanel和Grid是WPF中主要的5种内建面板,这些面板类都位于System.Windows.Controls命名空间下. 主要布局特 ...

  5. anaconda怎么运行python程序_Python中四种运行其他程序的方式,你知道吗?

    前言 在Python中,可以方便地使用os模块来运行其他脚本或者程序,这样就可以在脚本中直接使用其他脚本或程序提供的功能,而不必再次编写实现该功能的代码.为了更好地控制运行的进程,可以使用win32p ...

  6. vb中5种打开文件夹浏览框的方法总结(转)

    代码 众所周知,在vb中如果是打开某一个文件的话,非常简单,使用CommonDialog组件即可轻松完成,但是他只能选择文件,之后或许选取的文件路径,而如果想要浏览文件夹,就没这么方便了. 这里介绍3 ...

  7. 在ASP.Net中两种利用CSS实现多界面的方法(转)

    通过使页面动态加载不同CSS实现多界面 方法一: <%@page language="C#"%> <%@import namespace="System ...

  8. java 混音_Android中一种效果奇好的混音方法详解

    初识音频 从初中物理上我们就学到,声音是一种波.计算机只能处理离散的信号,通过收集足够多的离散的信号,来不断逼近波形,这个过程我们叫做采样.怎么样才能更好的还原声音信息呢?这里很自然引出两个概念了. ...

  9. mysql子查询的方式_分布式系统中一种迭代处理MYSQL子查询的方法

    1.技术背景 1.1 背景技术 在分布式mysql中间件系统,DML语句中,子查询需要可能涉及到多个数据分片,如果在DML语句使用子查询,需要首先解析出子查询的具体内容,然后根据路由把子查询发往到各个 ...

最新文章

  1. 那些消失的互联网中年人
  2. 全球科技大会鸿蒙,华为开发者大会:全球瞩目的“鸿蒙”面子和里子大格局
  3. 测试书籍推荐(收集)
  4. iOS9 App Thinning(应用瘦身)功能介绍
  5. 如何计算Nand Flash要传入的行地址和列地址
  6. 数位dp总结 之 从入门到模板(stO)
  7. HTTPS 原理解析
  8. Ditto —— windows 剪贴板增强小工具(复制粘贴多条记录)
  9. 大数据(7) - zookeeper的安装与使用
  10. Matlab中的基本绘图操作,Matlab中如何绘图
  11. weex的组件 web的使用(结合webview模块)
  12. 逆向Mac版WPS2019解除版本过期限制
  13. android手机无法root成功,安卓手机不能ROOT怎么办
  14. 文献管理——文献检索篇(一)
  15. win7开机后桌面变成黑色,此window副本不是正版
  16. LaTeX积分符号汇总
  17. sql server 中 SET ROWCOUNT 的具体用法
  18. 开发常用镜像资源替换为国内开源镜像(yum,compose,maven,docker,android sdk,npm,国内开源镜像汇总)...
  19. android 程序图标隐藏
  20. rtl8812au linux驱动下载,RTL8812AU_linux_v4.3.20_16317_20160108

热门文章

  1. 自学成才翁_以自学成才的设计师的身份在产品表旁导航。
  2. 手语识别_如何使用转移学习进行手语识别
  3. 编码程序教程_如何从编码教程到构建自己的项目
  4. node.js api接口_如何在Node.js API客户端中正常处理故障
  5. Homebrew更换源
  6. Python版常见的排序算法
  7. Flask框架——ORM数据库
  8. selenium的基本使用
  9. Hive 处理 json 数据
  10. 主成分分析(PCA)-最大方差解释