通用 ValueConverter,用于将枚举绑定到复选框






4.75/5 (12投票s)
通用 ValueConverter,用于将枚举绑定到复选框
摘要
很多时候,一个表单上有一组单选按钮与单个枚举关联。 很多开发人员会为每个单选按钮在ViewModel
中创建一个单独的属性。 我不喜欢这样做。 首先,我认为这在View
和ViewModel
之间存在太多的依赖关系。 它还会向ViewModel
添加一大堆属性,这只会使ViewModel
更大,并且需要额外的代码才能将其转换为枚举。 真正需要的是每个枚举的单个属性和一个通用的ValueConverter
。
背景
在多次不得不处理单选按钮和ViewModel
之后,我终于决定创建一种处理它们的通用方法。
实现
要将枚举绑定到一组单选按钮的IsChecked
属性,需要一个ValueConverter
;如果没有转换器,就无法将枚举绑定到bool
。 可以为每个单选按钮创建一个单独的ValueConverter
类,但这不是必需的,因为ValueConverter
方法具有一个参数,该参数通过使用Binding的ConverterParameter
参数在XAML中设置。 想法是每个单选按钮的IsChecked
参数都使用EnumValueConverter
绑定到Enumeration
属性,其ConverterParameter
等于一个string
,该string
是特定枚举的名称。
class EnumValueConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
if (value == null || parameter == null)
return false;
return value.ToString() == parameter.ToString();
}
public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
if (value == null || parameter == null)
return null;
var rtnValue = parameter.ToString();
try
{
object returnEnum = Enum.Parse(targetType, rtnValue);
return returnEnum;
}
catch
{
return null;
}
}
}
在示例代码中,我添加了三个调试方法来帮助查找错误,但为了清楚起见,已删除了这些方法。 可以看出,代码非常简单明了。 在Convert
方法中,使用ToString()
方法将ViewModel
中的枚举转换为string
,然后将其与ConverterParmeter
进行比较;如果相等,则返回的值为true
。 在ConvertBack
方法中,如果值参数存在,则使用Enum.Parse
方法将控制中的ConverterParmeter
转换为ViewModel
的相应枚举。 幸运的是,这可行,因为对于单选按钮,它们只需要处理更改为选中状态,因此无需处理更改为未选中状态;那是自动的。 如果Parse不起作用,则返回null
(对于null
值和参数参数也是如此,它没有效果,因为null
对于枚举无效(Binding不允许更改无效值))。
将XAML连接到属性和转换器非常简单。 在示例中,有一个非常简单的enum
public enum TestEnum
{
A, B, C
}
此枚举的ViewModel
中的属性也非常简单
public TestEnum EnumBinding
{
get
{
return _enumBinding;
}
set
{
if (_enumBinding != value)
{
_enumBinding = value;
if (PropertyChanged != null)
PropertyChanged(this, new
PropertyChangedEventArgs("EnumBinding"));
}
}
}
现在只需要XAML,其中包括转换器的资源定义和带有绑定定义的复选框,这些绑定定义使用转换器和ConverterParameter
<Window x:Class="GenericEnumValueConverter.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:GenericEnumValueConverter"
Title="Enumerator Value Converter Example"
Height="200" Width="250">
<Window.Resources>
<local:EnumValueConverter x:Key="EnumValueConverter"/>
</Window.Resources>
<StackPanel HorizontalAlignment="Center"
VerticalAlignment="Center">
<RadioButton Content="A"
IsChecked="{Binding EnumBinding,
Converter={StaticResource EnumValueConverter},
ConverterParameter=A}"/>
<RadioButton Content="B"
IsChecked="{Binding EnumBinding,
Converter={StaticResource EnumValueConverter},
ConverterParameter=B}"/>
<RadioButton Content="C"
IsChecked="{Binding EnumBinding,
Converter={StaticResource EnumValueConverter},
ConverterParameter=C}"/>
</StackPanel>
</Window>
实际示例包括一个TextBox
,用于确认枚举的属性实际上是单选按钮的值,以及一个包含错误值的额外单选按钮,用于显示XAML中存在错误枚举值时发生的情况(在调试期间,按下“Bad Value”单选按钮会在“输出”窗口中创建一个消息)。
结论
这是一种非常简洁的将枚举连接到单选按钮的方法。 相同的转换器也可以用于其他目的,只需添加一些额外的代码,例如根据枚举指定的状态设置控件的可见性(需要将bool
值转换为Visibility
枚举)。 它减少了ViewModel
的很多复杂性,并为所有枚举绑定到CheckBox
(或其他Control
)的实例使用单个转换器。 总之,这是一种非常简洁的减少代码和提高可维护性的方法。
历史
- 2011 年 10 月 15 日:初始版本