通用枚举值转换器实现

在开发过程中,经常会遇到需要将单选按钮与ViewModel中的枚举类型进行绑定的情况。许多开发者会选择为每个单选按钮创建一个单独的属性在ViewModel中,但这种做法会使得ViewModel与视图之间存在过多的依赖,同时也会使得ViewModel变得庞大,并且需要为每个属性编写额外的代码来进行枚举类型的转换。实际上,只需要为每个枚举类型提供一个属性,并且使用一个通用的转换器即可。

在处理了无数次单选按钮和ViewModel的绑定之后,决定创建一种通用的方式来处理它们。

实现

要将枚举类型绑定到一组单选按钮的IsChecked属性,需要一个ValueConverter,因为无法直接将枚举类型绑定到bool类型。虽然可以为每个单选按钮创建一个单独的ValueConverter类,但这不是必需的,因为ValueConverter的方法有一个参数,这个参数可以在XAML中通过Binding的ConverterParameter属性来设置。每个单选按钮的IsChecked属性将绑定到ViewModel中的枚举属性,使用EnumValueConverter,并设置ConverterParameter为特定枚举的名称字符串。

public 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中的枚举转换为字符串,然后与ConverterParameter进行比较;如果相等,则返回true。在ConvertBack方法中,使用Enum.Parse方法将ConverterParameter从控件转换为ViewModel中适当的枚举类型,如果值参数在单选按钮中被选中,则自动处理未选中状态的更改,因为单选按钮只需要处理被选中状态的更改。如果解析失败,则返回null(对于null值和参数参数,由于null对于枚举类型无效(绑定不允许无效值的更改),因此没有效果)。

将XAML绑定到属性和转换器非常简单。示例中有一个非常简单的枚举:

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”单选按钮会在输出窗口中创建一条消息)。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485