运行wpf_在WPF中一种较好的绑定Enums数据方法
引言
在你使用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.MethodParameters
的Enum
类型。最后,你添加的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数据方法相关推荐
- WPF中如何将ListViewItem双击事件绑定到Command
原文:WPF中如何将ListViewItem双击事件绑定到Command 今天的博客将介绍如何实现ListViewItem双击事件绑定到ViewModel中的Command.实现方法借助了Style中 ...
- 【面试题】CSS 中几种最常用的水平垂直居中的方法
目录 CSS 中几种最常用的水平垂直居中的方法 一.使用 margin:auto 二.使用 position:absolute 三.使用弹性布局 四.文本水平对齐和行高 五.使用网格布局 CSS 中几 ...
- python numpy读取数据_numpy中以文本的方式存储以及读取数据方法
这篇文章主要介绍了关于numpy中以文本的方式存储以及读取数据方法,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 Numpy中除了能够把数据以二进制文件的方式保存到文件中以外,还可以选 ...
- WPF中5种内建面板Canvas、StackPanel、WrapPanel、DockPanel、Grid分析
Canvas.StackPanel.WrapPanel.DockPanel和Grid是WPF中主要的5种内建面板,这些面板类都位于System.Windows.Controls命名空间下. 主要布局特 ...
- anaconda怎么运行python程序_Python中四种运行其他程序的方式,你知道吗?
前言 在Python中,可以方便地使用os模块来运行其他脚本或者程序,这样就可以在脚本中直接使用其他脚本或程序提供的功能,而不必再次编写实现该功能的代码.为了更好地控制运行的进程,可以使用win32p ...
- vb中5种打开文件夹浏览框的方法总结(转)
代码 众所周知,在vb中如果是打开某一个文件的话,非常简单,使用CommonDialog组件即可轻松完成,但是他只能选择文件,之后或许选取的文件路径,而如果想要浏览文件夹,就没这么方便了. 这里介绍3 ...
- 在ASP.Net中两种利用CSS实现多界面的方法(转)
通过使页面动态加载不同CSS实现多界面 方法一: <%@page language="C#"%> <%@import namespace="System ...
- java 混音_Android中一种效果奇好的混音方法详解
初识音频 从初中物理上我们就学到,声音是一种波.计算机只能处理离散的信号,通过收集足够多的离散的信号,来不断逼近波形,这个过程我们叫做采样.怎么样才能更好的还原声音信息呢?这里很自然引出两个概念了. ...
- mysql子查询的方式_分布式系统中一种迭代处理MYSQL子查询的方法
1.技术背景 1.1 背景技术 在分布式mysql中间件系统,DML语句中,子查询需要可能涉及到多个数据分片,如果在DML语句使用子查询,需要首先解析出子查询的具体内容,然后根据路由把子查询发往到各个 ...
最新文章
- 那些消失的互联网中年人
- 全球科技大会鸿蒙,华为开发者大会:全球瞩目的“鸿蒙”面子和里子大格局
- 测试书籍推荐(收集)
- iOS9 App Thinning(应用瘦身)功能介绍
- 如何计算Nand Flash要传入的行地址和列地址
- 数位dp总结 之 从入门到模板(stO)
- HTTPS 原理解析
- Ditto —— windows 剪贴板增强小工具(复制粘贴多条记录)
- 大数据(7) - zookeeper的安装与使用
- Matlab中的基本绘图操作,Matlab中如何绘图
- weex的组件 web的使用(结合webview模块)
- 逆向Mac版WPS2019解除版本过期限制
- android手机无法root成功,安卓手机不能ROOT怎么办
- 文献管理——文献检索篇(一)
- win7开机后桌面变成黑色,此window副本不是正版
- LaTeX积分符号汇总
- sql server 中 SET ROWCOUNT 的具体用法
- 开发常用镜像资源替换为国内开源镜像(yum,compose,maven,docker,android sdk,npm,国内开源镜像汇总)...
- android 程序图标隐藏
- rtl8812au linux驱动下载,RTL8812AU_linux_v4.3.20_16317_20160108