如何将RadioButtons绑定到一个枚举?

我有这样的枚举:

public enum MyLovelyEnum
{
  FirstSelection,
  TheOtherSelection,
  YetAnotherOne
};

我在DataContext中获得了一个属性:

public MyLovelyEnum VeryLovelyEnum { get; set; }

我的WPF客户端中有三个RadioButton。

<RadioButton Margin="3">First Selection</RadioButton>
<RadioButton Margin="3">The Other Selection</RadioButton>
<RadioButton Margin="3">Yet Another one</RadioButton>

现在我该如何将RadioButtons绑定到属性以进行正确的双向绑定?


你可以使用更通用的转换器

public class EnumBooleanConverter : IValueConverter
{
  #region IValueConverter Members
  public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    string parameterString = parameter as string;
    if (parameterString == null)
      return DependencyProperty.UnsetValue;

    if (Enum.IsDefined(value.GetType(), value) == false)
      return DependencyProperty.UnsetValue;

    object parameterValue = Enum.Parse(value.GetType(), parameterString);

    return parameterValue.Equals(value);
  }

  public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    string parameterString = parameter as string;
    if (parameterString == null)
        return DependencyProperty.UnsetValue;

    return Enum.Parse(targetType, parameterString);
  }
  #endregion
}

在您使用的XAML-Part中:

<Grid>
    <Grid.Resources>
      <l:EnumBooleanConverter x:Key="enumBooleanConverter" />
    </Grid.Resources>
    <StackPanel >
      <RadioButton IsChecked="{Binding Path=VeryLovelyEnum, Converter={StaticResource enumBooleanConverter}, ConverterParameter=FirstSelection}">first selection</RadioButton>
      <RadioButton IsChecked="{Binding Path=VeryLovelyEnum, Converter={StaticResource enumBooleanConverter}, ConverterParameter=TheOtherSelection}">the other selection</RadioButton>
      <RadioButton IsChecked="{Binding Path=VeryLovelyEnum, Converter={StaticResource enumBooleanConverter}, ConverterParameter=YetAnotherOne}">yet another one</RadioButton>
    </StackPanel>
</Grid>

您可以进一步简化接受的答案。 除了将枚举类型输入为xaml中的字符串以及在转换器中执行更多工作之外,您可以显式传递enum值而不是字符串表示形式,CrimsonX评论道,在编译时抛出错误而不是运行时:

ConverterParameter = {x:静态本地:YourEnumType.Enum1}

<StackPanel>
    <StackPanel.Resources>          
        <local:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />          
    </StackPanel.Resources>
    <RadioButton IsChecked="{Binding Path=YourEnumProperty, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static local:YourEnumType.Enum1}}" />
    <RadioButton IsChecked="{Binding Path=YourEnumProperty, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static local:YourEnumType.Enum2}}" />
</StackPanel>

然后简化转换器:

public class EnumToBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value.Equals(parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value.Equals(true) ? parameter : Binding.DoNothing;
    }
}

注 - 在同一个容器中的多组RadioButton(11年2月17日):

在xaml中,如果单选按钮共享同一个父容器,则选择其中一个将取消选择该容器内的所有其他容器(即使它们绑定到不同的属性)。 因此,尽量让你的RadioButton的绑定到一个公共属性中,像堆栈面板一样分组在一起。 在您的相关RadioButtons不能共享单个父容器的情况下,将每个RadioButton的GroupName属性设置为一个通用值,以对它们进行逻辑分组。

注 - 嵌套在类中的枚举类型(11年4月28日):

如果枚举类型嵌套在类中(而不是直接嵌套在名称空间中),则可以使用'+'语法访问XAML中的枚举,如问题的(未标记的)答案中所述无法找到WPF中静态引用的枚举类型:

ConverterParameter = {x:静态本地:YourClass + YourNestedEnumType.Enum1}

但是,由于此Microsoft Connect问题,VS2010中的设计器将不再载入"Type 'local:YourClass+YourNestedEnumType' was not found." ,但该项目编译并运行成功。 当然,如果可以直接将枚举类型移动到名称空间,则可以避免此问题。

编辑(10月16 '10):

感谢anon提示返回Binding.DoNothing而不是DependencyProperty.UnsetValue。

编辑(4月5 '11):

简化的ConvertBack的if-else使用三元运算符。

编辑(1月27'12):

如果使用Enum标志,转换器将如下所示:

public class EnumToBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return ((Enum)value).HasFlag((Enum)parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value.Equals(true) ? parameter : Binding.DoNothing;
    }
}

编辑(15年5月7日):

在Nullable Enum的情况下(在问题中没有被问到,但在某些情况下可能需要,例如ORM从DB返回null或者在程序逻辑中没有提供该值时可能有意义),请记住添加在Convert方法中进行初始空检查并返回适当的bool值,通常为false(如果您不想要任何单选按钮),如下所示:

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null) {
            return false; // or return parameter.Equals(YourEnumType.SomeDefaultValue);
        }
        return value.Equals(parameter);
    }

对于EnumToBooleanConverter答案:代替返回DependencyProperty.UnsetValue,考虑在单选按钮IsChecked值变为false的情况下返回Binding.DoNothing。 前者表示一个问题(并且可能向用户显示红色矩形或类似的验证指示符),而后者仅表示不应该做任何事情,这就是在这种情况下需要的。

http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.convertback.aspx http://msdn.microsoft.com/en-us/library/system.windows.data.binding .donothing.aspx

链接地址: http://www.djcxy.com/p/34469.html

上一篇: How to bind RadioButtons to an enum?

下一篇: Access parent DataContext from DataTemplate