如何将单选按钮绑定到枚举?

473

我有一个像这样的枚举:

public enum MyLovelyEnum
{
    FirstSelection,
    TheOtherSelection,
    YetAnotherOne
};

我在我的DataContext中有一个属性:

public MyLovelyEnum VeryLovelyEnum { get; set; }

我在我的WPF客户端中有三个单选按钮。

<RadioButton Margin="3">First Selection</RadioButton>
<RadioButton Margin="3">The Other Selection</RadioButton>
<RadioButton Margin="3">Yet Another one</RadioButton>
现在我该如何将单选按钮绑定到属性以进行适当的双向绑定?

4
如果你想在XAML中不指定单独的RadioButton来完成这个任务,我建议使用一个ListBox来绑定enum值,例如这样这样,并覆盖item template以使用RadioButton,例如这样 - Rachel
11个回答

630

你可以进一步简化被接受的答案。不需要在XAML中将枚举类型作为字符串进行输入,也不需要在转换器中进行额外的工作。相反,你可以明确传递枚举值而不是字符串表示。正如CrimsonX所评论的那样,这样做会在编译时抛出错误而不是运行时:

ConverterParameter={x:Static local:YourEnumType.Enum1}

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

然后简化转换器:

public class ComparisonConverter : 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) == true ? parameter : Binding.DoNothing;
    }
}

编辑(2010年12月16日):

感谢匿名用户建议返回Binding.DoNothing而不是DependencyProperty.UnsetValue。


注意 - 同一容器中的多组RadioButton(2011年2月17日):

在XAML中,如果单选按钮共享同一个父容器,则选择一个将取消该容器内的所有其他项(即使它们绑定到不同的属性)。因此,请尝试将绑定到共同属性的RadioButton分组放在自己的容器中,例如StackPanel。在相关的RadioButton不能共享单一父容器的情况下,可以将每个单选按钮的GroupName属性设置为相同的值以逻辑分组。

编辑(2011年4月5日):

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

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

如果您的枚举类型嵌套在类中(而不是直接在命名空间中),则您可能可以使用“+”语法在XAML中访问该枚举,如问题的一个(未标记)答案所述:

ConverterParameter={x:Static local:YourClass+YourNestedEnumType.Enum1}

由于这个Microsoft Connect问题,VS2010中的设计器将不再加载,指出"Type 'local:YourClass+YourNestedEnumType' was not found.",但项目可以成功编译和运行。当然,如果您能够将枚举类型移动到命名空间中,则可以避免此问题。

编辑(2012年1月27日):

如果使用枚举标志,则转换器应如下所示:
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;
    }
}

编辑(2015年5月7日):

如果是可空枚举类型(并非在问题中提到,但某些情况下可能需要,例如ORM从数据库返回null或程序逻辑中提供值没有意义的情况),请记得在Convert方法中添加一个初始的null检查,并返回适当的布尔值,通常是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);
    }

注意 - NullReferenceException(2018年10月10日):

更新了示例以消除抛出NullReferenceException的可能性。 `IsChecked`是可为空的类型,因此返回`Nullable`似乎是一个合理的解决方案。

29
我同意,我认为这是更好的解决方案。此外,如果枚举值发生改变,使用此转换将导致项目在编译时而不是运行时中断,这是一个很大的优势。 - CrimsonX
5
这肯定比被接受的方案好多了。+1 - OrPaz
7
好的解决方案。我会补充说,这实际上只是一个比较转换器,用于比较两个值。它可以使用比EnumToBooleanConverter更通用的名称,例如ComparisonConverter。 - MikeKulls
5
@ Scott,非常好。这个转换器在任何情况下都很好,无论有没有Flags属性。但是,在大多数情况下,直接将此过滤器用作具有枚举标志的转换器是愚蠢的。原因是您应该使用先前值实现布尔运算(|=或^=)以获得正确的结果,但转换器无法访问先前值。然后,您应该为每个枚举值添加一个bool,并在MVVM模型中自己进行适当的布尔运算。但感谢提供的所有信息,非常有用。 - Eric Ouellet
2
在Windows Phone 8中(可能适用于Win Store应用程序),我们没有x:static,因此我们无法直接在此处使用解决方案。但是,IDE / Complier足够智能,并针对所有字符串文字查找字符串(我猜的)。例如,这个可以工作 <RadioButton IsChecked="{Binding TrackingMode,ConverterParameter = Driving,Converter = {StaticResource EnumToBooleanConverter},Mode = TwoWay}" />任何驾驶中的拼写错误都将在设计/编译时而不是运行时被捕获。 - Adarsha
显示剩余13条评论

417

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

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 部分中使用:

<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>

57
对我来说,这个方法很有效。此外,我还修改了ConvertBack函数,以便在“false”时返回UnsetValue。因为Silverlight(以及WPF proper)调用转换器两次-一次是取消设置旧的单选按钮值,另一次是设置新的值。我将其他内容悬挂在属性设置器上,因此我只想让它被调用一次。--如果参数字符串为空或者值等于false,则返回DependencyProperty.UnsetValue。 - MarcE
8
据我所知,除非单选按钮位于不同的组中(而且据我所知,没有设置 GroupName 且有相同父级的按钮默认属于同一组),否则必须执行此操作。否则,对属性“bounce”的设置将导致奇怪的行为。 - nlawalker
2
是的,但如果您在将其设置为false时调用Unset,则它不是真正的EnumToBooleanConverter,而更像是EnumToRadioButtonConverter。因此,我在我的属性setter中检查值是否不同:如果(_myEnumBackingField == value)返回; - Stéphane
11
这个解决方案的绑定只能单向正确工作。我无法通过将绑定的属性分配给不同的值来以编程方式切换单选按钮。如果您想要一个正常工作且更好的解决方案,请使用Scott的方法。 - TtT23
3
重复上面的注释:这不是双向工作的。您无法设置属性并正确更改单选按钮的 IsChecked。你真的想使用下面 Scott 的方法。 - Clint StLaurent
显示剩余7条评论

27
对于EnumToBooleanConverter的答案: 当单选按钮的IsChecked值变为false时,不要返回DependencyProperty.UnsetValue,而应该返回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


Silverlight 中没有 Binding.Nothing,这只适用于 WPF。请使用 null 代替。 - Alexander Vasilyev
1
绑定。在UWP中也消失了Nothing。 - BlackICE

5

我使用类似于使用ListBox和DataTemplate的方法来实现双向绑定,你也应该这样做。 - Bryan Anderson
这个 bug:http://geekswithblogs.net/claraoscura/archive/2008/10/17/125901.aspx 给我带来了烦恼。 - Slampen
3
目前为止,这是最佳解决方案,其他任何方法都会导致冗余代码。(另一个使用ListBox的例子 - H.B.

3
我创建了一个新的类来处理将RadioButton和CheckBox绑定到枚举类型。它适用于标记枚举(具有多个复选框选择)和非标记枚举,适用于单选框或单选按钮。它还不需要任何ValueConverters。 一开始可能看起来更加复杂,但是一旦将此类复制到您的项目中,就完成了。它是通用的,因此可以轻松地重用于任何枚举。
public class EnumSelection<T> : INotifyPropertyChanged where T : struct, IComparable, IFormattable, IConvertible
{
  private T value; // stored value of the Enum
  private bool isFlagged; // Enum uses flags?
  private bool canDeselect; // Can be deselected? (Radio buttons cannot deselect, checkboxes can)
  private T blankValue; // what is considered the "blank" value if it can be deselected?

  public EnumSelection(T value) : this(value, false, default(T)) { }
  public EnumSelection(T value, bool canDeselect) : this(value, canDeselect, default(T)) { }
  public EnumSelection(T value, T blankValue) : this(value, true, blankValue) { }
  public EnumSelection(T value, bool canDeselect, T blankValue)
  {
    if (!typeof(T).IsEnum) throw new ArgumentException($"{nameof(T)} must be an enum type"); // I really wish there was a way to constrain generic types to enums...
    isFlagged = typeof(T).IsDefined(typeof(FlagsAttribute), false);

    this.value = value;
    this.canDeselect = canDeselect;
    this.blankValue = blankValue;
  }

  public T Value
  {
    get { return value; }
    set 
    {
      if (this.value.Equals(value)) return;
      this.value = value;
      OnPropertyChanged();
      OnPropertyChanged("Item[]"); // Notify that the indexer property has changed
    }
  }

  [IndexerName("Item")]
  public bool this[T key]
  {
    get
    {
      int iKey = (int)(object)key;
      return isFlagged ? ((int)(object)value & iKey) == iKey : value.Equals(key);
    }
    set
    {
      if (isFlagged)
      {
        int iValue = (int)(object)this.value;
        int iKey = (int)(object)key;

        if (((iValue & iKey) == iKey) == value) return;

        if (value)
          Value = (T)(object)(iValue | iKey);
        else
          Value = (T)(object)(iValue & ~iKey);
      }
      else
      {
        if (this.value.Equals(key) == value) return;
        if (!value && !canDeselect) return;

        Value = value ? key : blankValue;
      }
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;

  private void OnPropertyChanged([CallerMemberName] string propertyName = "")
  {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }
}

关于如何使用它,假设你有一个枚举用于手动或自动运行任务,并可安排在一周的任何日子,还有一些可选选项...

public enum StartTask
{
  Manual,
  Automatic
}

[Flags()]
public enum DayOfWeek
{
  Sunday = 1 << 0,
  Monday = 1 << 1,
  Tuesday = 1 << 2,
  Wednesday = 1 << 3,
  Thursday = 1 << 4,
  Friday = 1 << 5,
  Saturday = 1 << 6
}

public enum AdditionalOptions
{
  None = 0,
  OptionA,
  OptionB
}
现在,让我们来看一下如何轻松使用这个类:
public class MyViewModel : ViewModelBase
{
  public MyViewModel()
  {
    StartUp = new EnumSelection<StartTask>(StartTask.Manual);
    Days = new EnumSelection<DayOfWeek>(default(DayOfWeek));
    Options = new EnumSelection<AdditionalOptions>(AdditionalOptions.None, true, AdditionalOptions.None);
  }

  public EnumSelection<StartTask> StartUp { get; private set; }
  public EnumSelection<DayOfWeek> Days { get; private set; }
  public EnumSelection<AdditionalOptions> Options { get; private set; }
}

使用这个类绑定复选框和单选按钮非常简单:

<StackPanel Orientation="Vertical">
  <StackPanel Orientation="Horizontal">
    <!-- Using RadioButtons for exactly 1 selection behavior -->
    <RadioButton IsChecked="{Binding StartUp[Manual]}">Manual</RadioButton>
    <RadioButton IsChecked="{Binding StartUp[Automatic]}">Automatic</RadioButton>
  </StackPanel>
  <StackPanel Orientation="Horizontal">
    <!-- Using CheckBoxes for 0 or Many selection behavior -->
    <CheckBox IsChecked="{Binding Days[Sunday]}">Sunday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Monday]}">Monday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Tuesday]}">Tuesday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Wednesday]}">Wednesday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Thursday]}">Thursday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Friday]}">Friday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Saturday]}">Saturday</CheckBox>
  </StackPanel>
  <StackPanel Orientation="Horizontal">
    <!-- Using CheckBoxes for 0 or 1 selection behavior -->
    <CheckBox IsChecked="{Binding Options[OptionA]}">Option A</CheckBox>
    <CheckBox IsChecked="{Binding Options[OptionB]}">Option B</CheckBox>
  </StackPanel>
</StackPanel>
  1. 当用户界面加载时,“手动”单选按钮将被选中,您可以在“手动”或“自动”之间更改选择,但其中一个必须始终被选中。
  2. 每个星期的每天都将未被选中,但任何数量的它们都可以被选中或取消选中。
  3. “选项A”和“选项B”最初都未被选中。您可以选择其中一个进行勾选,勾选其中一个将取消另一个(类似于RadioButton),但现在您也可以取消选中它们两个(这是WPF的RadioButton无法做到的,因此在这里使用了CheckBox)。

假设您在StartTask枚举中有3个项目,例如{ Undefined,Manual,Automatic }。 您希望默认为Undefined,因为在用户设置值之前它是未定义的。另外:如何处理SelectedItem? 您的ViewModel没有SelectedStartTask。 - user1040323
在我的ViewModel中,StartUp属性是一个EnumSelection<StartTask>对象。如果您查看EnumSelection<T>的定义,您可以看到它有一个Value属性。因此,视图模型不需要有一个“SelectedStartTask”。您将使用StartUp.Value。至于默认值为Undefined,参见第三个枚举AdditionalOptions,它具有None而不是Undefined,但您可以将其名称更改为任何您想要的名称。 - Nick

3
对于UWP来说,情况并不那么简单:你必须通过额外的步骤将一个字段值作为参数传递。

示例1

适用于WPF和UWP。

<MyControl>
    <MyControl.MyProperty>
        <Binding Converter="{StaticResource EnumToBooleanConverter}" Path="AnotherProperty">
            <Binding.ConverterParameter>
                <MyLibrary:MyEnum>Field</MyLibrary:MyEnum>
            </Binding.ConverterParameter>
        </MyControl>
    </MyControl.MyProperty>
</MyControl>

示例2

适用于WPF和UWP。

...
<MyLibrary:MyEnum x:Key="MyEnumField">Field</MyLibrary:MyEnum>
...

<MyControl MyProperty="{Binding AnotherProperty, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={StaticResource MyEnumField}}"/>

例子 3

仅适用于WPF!

<MyControl MyProperty="{Binding AnotherProperty, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static MyLibrary:MyEnum.Field}}"/>

UWP不支持x:Static,所以示例3不可行;假设您选择示例1,结果是更冗长的代码。 示例2稍微好一些,但仍不理想。

解决方案

public abstract class EnumToBooleanConverter<TEnum> : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var Parameter = parameter as string;

        if (Parameter == null)
            return DependencyProperty.UnsetValue;

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

        return Enum.Parse(typeof(TEnum), Parameter).Equals(value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        var Parameter = parameter as string;
        return Parameter == null ? DependencyProperty.UnsetValue : Enum.Parse(typeof(TEnum), Parameter);
    }
}

接下来,对于每个你想支持的类型,定义一个将枚举类型包装起来的转换器。

public class MyEnumToBooleanConverter : EnumToBooleanConverter<MyEnum>
{
    //Nothing to do!
}

它必须被包装的原因是因为在ConvertBack方法中似乎没有办法引用该类型; 包装可解决此问题。如果您选择前两个示例之一,则可以直接引用参数类型,消除了从包装类继承的必要性;如果您希望在一行中完成所有操作,并且尽可能地减少冗余,那么后一种解决方案是理想的。

使用方式类似于示例2,但实际上更简洁。

<MyControl MyProperty="{Binding AnotherProperty, Converter={StaticResource MyEnumToBooleanConverter}, ConverterParameter=Field}"/>
缺点是您必须为每种要支持的类型定义一个转换器。

2
你可以动态创建单选按钮,ListBox 可以帮助你完成这个任务,不需要使用转换器,非常简单。 具体步骤如下:
  • 创建一个 ListBox,并将其 ItemsSource 设置为枚举类型 MyLovelyEnum,并将 ListBox 的 SelectedItem 绑定到属性 VeryLovelyEnum
  • 然后会为每个 ListBoxItem 创建单选按钮。
  • 第一步:将该枚举添加到窗口、用户控件或网格等的静态资源中。
    <Window.Resources>
        <ObjectDataProvider MethodName="GetValues"
                            ObjectType="{x:Type system:Enum}"
                            x:Key="MyLovelyEnum">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="local:MyLovelyEnum" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>
  • 步骤2:使用列表框和控件模板将每个项目填充为单选按钮。
    <ListBox ItemsSource="{Binding Source={StaticResource MyLovelyEnum}}" SelectedItem="{Binding VeryLovelyEnum, Mode=TwoWay}" >
        <ListBox.Resources>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <RadioButton
                                Content="{TemplateBinding ContentPresenter.Content}"
                                IsChecked="{Binding Path=IsSelected,
                                RelativeSource={RelativeSource TemplatedParent},
                                Mode=TwoWay}" />
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.Resources>
    </ListBox>
优点是:如果某天您的枚举类发生更改,您不需要更新GUI(XAML文件)。

References: https://brianlagunas.com/a-better-way-to-data-bind-enums-in-wpf/


如果EnumProperty已经有值,这种方法将不起作用。public MyEnum EProperty {get; set;} = MyEnum.Value1。RadioButton不会被选中。 - DirtyNative

1
这也适用于复选框
public class EnumToBoolConverter:IValueConverter
{
    private int val;
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        int intParam = (int)parameter;
        val = (int)value;

        return ((intParam & val) != 0);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        val ^= (int)parameter;
        return Enum.Parse(targetType, val.ToString());
    }
}

将一个枚举类型绑定到多个复选框。


1
我向你表示衷心的感谢,感谢你为我所做的恩惠。它对我非常有效。 - Elham Azadfar

1

处理这种情况的一种方法是在您的 ViewModel 类中拥有单独的 bool 属性。以下是我如何处理这种情况的方法:

ViewModel:

public enum MyLovelyEnum { FirstSelection, TheOtherSelection, YetAnotherOne };
private MyLovelyEnum CurrentSelection;

public bool FirstSelectionProperty
{
    get
    {
        return CurrentSelection == MyLovelyEnum.FirstSelection;
    }
    set
    {
        if (value)
            CurrentSelection = MyLovelyEnum.FirstSelection;
    }
}

public bool TheOtherSelectionProperty
{
    get
    {
        return CurrentSelection == MyLovelyEnum.TheOtherSelection;
    }
    set
    {
        if (value)
            CurrentSelection = MyLovelyEnum.TheOtherSelection;
    }
}

public bool YetAnotherOneSelectionProperty
{
    get
    {
        return CurrentSelection == MyLovelyEnum.YetAnotherOne;
    }
    set
    {
        if (value)
            CurrentSelection = MyLovelyEnum.YetAnotherOne;
    }
}

XAML:

<RadioButton IsChecked="{Binding SimilaritySort, Mode=TwoWay}">Similarity</RadioButton>
<RadioButton IsChecked="{Binding DateInsertedSort, Mode=TwoWay}">Date Inserted</RadioButton>
<RadioButton IsChecked="{Binding DateOfQuestionSort, Mode=TwoWay}">Date of Question</RadioButton>
<RadioButton IsChecked="{Binding DateModifiedSort, Mode=TwoWay}">Date Modified</RadioButton>
它不像其他解决方案那样强大或动态,但好处是它非常自包含,不需要创建自定义转换器或类似的东西。

是的,除非这是一个经常发生的情况,否则就得“认输”并接受WPF没有内在便利支持的事实,然后采取其他方法。对于那些偶尔出现的情况,我认为这样做有助于提高可维护性。 - Jonas

0
一种使用 Nullable 的 UWP 双向绑定解决方案: C# 部分:
public class EnumConverter : IValueConverter
{
    public Type EnumType { get; set; }
    public object Convert(object value, Type targetType, object parameter, string lang)
    {
        if (parameter is string enumString)
        {
            if (!Enum.IsDefined(EnumType, value)) throw new ArgumentException("value must be an Enum!");
            var enumValue = Enum.Parse(EnumType, enumString);
            return enumValue.Equals(value);
        }
        return value.Equals(Enum.ToObject(EnumType,parameter));
    }

    public object ConvertBack(object value, Type targetType, object parameter, string lang)
    {
        if (parameter is string enumString)
            return value?.Equals(true) == true ? Enum.Parse(EnumType, enumString) : null;
        return value?.Equals(true) == true ? Enum.ToObject(EnumType, parameter) : null;
    }
}

这里的null值充当了Binding.DoNothing的作用。

private YourEnum? _yourEnum = YourEnum.YourDefaultValue; //put a default value here
public YourEnum? YourProperty
{
    get => _yourEnum;
    set{
        if (value == null) return;
        _yourEnum = value;
    }
}

Xaml 部分:

...
<Page.Resources>
    <ResourceDictionary>
        <helper:EnumConverter x:Key="YourConverter" EnumType="yournamespace:YourEnum" />
    </ResourceDictionary>
</Page.Resources>
...
<RadioButton GroupName="YourGroupName" IsChecked="{Binding Converter={StaticResource YourConverter}, Mode=TwoWay, Path=YourProperty, ConverterParameter=YourEnumString}">
    First way (parameter of type string)
</RadioButton>
<RadioButton GroupName="LineWidth">
    <RadioButton.IsChecked>
        <Binding
            Converter="{StaticResource PenWidthConverter}"
            Mode="TwoWay"   Path="PenWidth">
            <Binding.ConverterParameter>
                <yournamespace:YourEnum>YourEnumString</yournamespace:YourEnum>
            </Binding.ConverterParameter>
        </Binding>
    </RadioButton.IsChecked>
    Second way (parameter of type YourEnum (actually it was converted to int when passed to converter))
</RadioButton>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,