引言

在你使用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>
<ObjectDataProvider
x: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>
<ComboBox
MinWidth="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>
<ComboBox
MinWidth="150"
HorizontalAlignment="Center"
ItemsSource="{Binding Source={StaticResource DataFromEnum}}">
</ComboBox>
<ComboBox
MinWidth="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中一种较好的绑定Enums数据方法的更多相关文章

  1. WPF中的ListBox实现按块显示元素的方法

    本文实例讲述了WPF中的ListBox实现按块显示元素的方法.分享给大家供大家参考,具体如下: 注意:需要设置ListBox的属性 ScrollViewer.HorizontalScrollBarVi ...

  2. WPF中ItemsControl应用虚拟化时找到子元素的方法

    原文:WPF中ItemsControl应用虚拟化时找到子元素的方法  wpf的虚拟化技术会使UI的控件只初始化看的到的子元素, 而不是所有子元素都被初始化,这样会提高UI性能. 但是我们经常会遇到一个 ...

  3. 整理:WPF中应用附加事件制作可以绑定命令的其他事件

    原文:整理:WPF中应用附加事件制作可以绑定命令的其他事件 目的:应用附加事件的方式定义可以绑定的事件,如MouseLeftButton.MouseDouble等等 一.定义属于Control的附加事 ...

  4. 转:WPF中ListBox的创建和多种绑定用法

    先从最容易的开始演示ListBox控件的创建. Adding ListBox Items下面的代码是向ListBox控件中添加多项ListBoxItem集合.XAML代码如下:<ListBox ...

  5. WPF中使用相对资源来进行绑定,数据源是通过DataContext来指定的

    1. 最外层是Window是对象,Window的ItemsControl使用了ItemsTemplate,然后在ItemsTemplate中要绑定Language属性, 而整个Window的数据源是通 ...

  6. WPF中三种方法得到当前屏幕的宽和高

    WPF程序中的单位是与设备无关的单位,每个单位是1/96英寸,如果电脑的DPI设置为96(每个英寸96个像素),那么此时每个WPF单位对应一个像素,不过如果电脑的DPI设备为120(每个英寸120个像 ...

  7. .Net中几种常见的页面跳转传值方法

    1.ASP Server对象Execute方法 ASP Server对象的Execute方法可以在执行当前页面的过程中将另一个页面执行结果的内容插入到当前页面的输出中.Execute方法带一个参数,是 ...

  8. android在代码中四种设置控件背景颜色的方法(包含RGB)

    转载请注明出处: http://blog.csdn.net/fth826595345/article/details/9208771  TextView tText=(TextView) findVi ...

  9. Javascript中两种最通用的定义类的方法

    在Javascript中,一切都是对象,包括函数.在Javascript中并没有真正的类,不能像C#,PHP等语言中用 class xxx来定义.但Javascript中提供了一种折中的方案:把对象定 ...

随机推荐

  1. hystrix(8) 插件

    上一节讲到HystrixCommand的执行流程. Hystrix内部将一些模块实现成了插件,并且提供了用户提供自己的实现,通过配置来替换插件.Hystrix提供了5个插件,分别为并发相关插件(Hys ...

  2. springboot中关于Long类型返回前端精度丢失问题处理

    使用了HuTool这个雪花算法后,会出现丢失精度的问题 hutool算法使用地址 对于一些大的业务表,自增主键这里 接口层得注意下是否会产生大数值 设计接口的时候采用String类型. 在项目中,我们 ...

  3. oh-my-zsh超级终端

    _ _ ___ | |__ _ __ ___ _ _ _______| |__ / _ \| '_ \ _____| '_ ` _ \| | | |____|_ / __| '_ \ | (_) | ...

  4. Redis利用,攻击内网(ssrf)

    Redis语法 REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. Redis是一个开源的使用ANSI C ...

  5. vulnhub-Os-hackNos-3

    vulnhub-Os-hackNos-3 nmap 192.168.114.0/24 查看存活主机,发现192.168.114.142. 具体探究: 发现80和22端口是开放的. dirb没扫出来啥, ...

  6. 《我想进大厂》之MQ夺命连环11问

    继之前的mysql夺命连环之后,我发现我这个标题被好多套用的,什么夺命zookeeper,夺命多线程一大堆,这一次,开始面试题系列MQ专题,消息队列作为日常常见的使用中间件,面试也是必问的点之一,一起 ...

  7. Spark Parquet详解

    Spark - Parquet 概述 Apache Parquet属于Hadoop生态圈的一种新型列式存储格式,既然属于Hadoop生态圈,因此也兼容大多圈内计算框架(Hadoop.Spark),另外 ...

  8. Hadoop框架:HDFS读写机制与API详解

    本文源码:GitHub·点这里 || GitEE·点这里 一.读写机制 1.数据写入 客户端访问NameNode请求上传文件: NameNode检查目标文件和目录是否已经存在: NameNode响应客 ...

  9. 【性能监控-Perfmon工具】Perfmon工具使用教程

    一.Perfmon工具简介 Perfmon是一款Windows自带的性能监控工具,提供了图表化的系统性能实时监视器.性能日志和警报管理.通过添加性能计数器可以实现对CPU.内存.网络.磁盘.进程等多类 ...

  10. Python练习题 014:完数

    [Python练习题 014] 一个数如果恰好等于它的因子之和,这个数就称为"完数".例如6=1+2+3.编程找出1000以内的所有完数. -------------------- ...