- A+
概述
本文讲述下拉框和枚举类型进行绑定的一些操作。
下拉框的基本操作
设计部分:
<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】前言与目录