在WPF中将单选按钮组绑定到属性

35

假设我有以下内容:

<RadioButton GroupName="Group1" IsChecked="{Binding Path=RadioButton1IsChecked}" />
<RadioButton GroupName="Group1" IsChecked="{Binding Path=RadioButton2IsChecked}" />

然后在我的数据源类中我有:

public bool RadioButton1IsChecked { get; set; }
public bool RadioButton2IsChecked { get; set; }
public enum RadioButtons { RadioButton1, RadioButton2, None }
public RadioButtons SelectedRadioButton
{
    get
    {
        if (this.RadioButtonIsChecked) 
            return RadioButtons.RadioButton1;
        else if (this.RadioButtonIsChecked) 
            return RadioButtons.RadioButton2;
        else 
            return RadioButtons.None;
     }
}

我能否直接将我的单选按钮绑定到SelectedRadioButton属性?我只需要RadioButton1IsCheckedRadioButton2IsChecked属性来计算所选的单选按钮。


这篇博客文章可能会有所帮助。 - Jake Berger
请查看我在相关问题上的回答,它应该会有所帮助。SelectedItem绑定到感兴趣的属性。 - H.B.
4
我更喜欢:https://dev59.com/zXRC5IYBdhLWcg3wJNif - quetzalcoatl
1
https://dev59.com/zXRC5IYBdhLWcg3wJNif#2908885 - Mark Ingram
可能是如何将RadioButton绑定到枚举?的重复问题。 - John
4个回答

65

声明一个类似于以下枚举的枚举类型:

enum RadioOptions {Option1, Option2}

XAML:

<RadioButton IsChecked="{Binding SelectedOption, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static local:RadioOptions.Option1}}"/>
<RadioButton IsChecked="{Binding SelectedOption, Converter={StaticResource EnumBooleanConverter}, ConverterParameter={x:Static local:RadioOptions.Option2}}"/>

转换器类:

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

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

1
被接受的答案有什么功能上的区别? - Jerther
11
被接受的答案接受一个字符串参数并将其转换为枚举类型。这个方法直接接受一个枚举值,这是一个更好的做法,如果参数不正确将无法编译。 - Artfunkel

20
<RadioButton GroupName="Group1" IsChecked="{Binding Path=SelectedRadioButton, Converter={StaticResource EnumBooleanConverter}, ConverterParameter=RadioButton1}" />
<RadioButton GroupName="Group1" IsChecked="{Binding Path=SelectedRadioButton, Converter={StaticResource EnumBooleanConverter}, ConverterParameter=RadioButton2}" />
public enum RadioButtons { RadioButton1, RadioButton2, None }
public RadioButtons SelectedRadioButton {get;set;}

 public class EnumBooleanConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var ParameterString = parameter as string;
            if (ParameterString == null)
                return DependencyProperty.UnsetValue;

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

            object paramvalue = Enum.Parse(value.GetType(), ParameterString);
            return paramvalue.Equals(value);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var ParameterString = parameter as string;
            var valueAsBool = (bool) value;

            if (ParameterString == null || !valueAsBool)
            {
                try
                {
                    return Enum.Parse(targetType, "0");
                }
                catch (Exception)
                {
                    return DependencyProperty.UnsetValue;
                }
            }
            return Enum.Parse(targetType, ParameterString);
        }
    }

当任何单选按钮的“IsChecked”属性设置为“false”时,这是否会将“SelectedRadioButton”值设置为“RadioButtons.None”(通过执行“return Enum.Parse(targetType, "0");”)? - O. R. Mapper

5
我们可以动态创建单选按钮,ListBox 可以帮助我们实现这一点,无需转换器,非常简单。 优点如下: 如果您的枚举类在某一天发生更改,您不需要更新 GUI(XAML 文件)。
以下是步骤: 创建一个 ListBox,并将 ItemsSource 设置为枚举并将 ListBox 的 SelectedItem 绑定到 Selected 属性。 然后会为每个 ListBoxItem 创建单选按钮。
public enum RadioButtons
{ 
   RadioButton1, 
   RadioButton2, 
   None
}
  • 步骤1:将该枚举添加到您的窗口、用户控件或网格等静态资源中。
    <Window.Resources>
        <ObjectDataProvider MethodName="GetValues"
                            ObjectType="{x:Type system:Enum}"
                            x:Key="RadioButtons">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="local:RadioButtons" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>
  • 步骤2: 使用列表框和控件模板,将每个项目填充为单选按钮。
    <ListBox ItemsSource="{Binding Source={StaticResource RadioButtons}}" SelectedItem="{Binding SelectedRadioButton, 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>

现在,尽情享受吧~

参考资料: https://brianlagunas.com/a-better-way-to-data-bind-enums-in-wpf/


-1

XAML:

<RadioButton IsChecked="{Binding Path=SelectedOption, UpdateSourceTrigger=PropertyChanged}">Option1</RadioButton>
<RadioButton IsChecked="{Binding Path=SelectedOption, UpdateSourceTrigger=PropertyChanged, Converter={v:NotBoolenConverter}}">Option2</RadioButton>

转换器:

public class NotBoolenConverter : IValueConverter
    {
        public NotBoolenConverter()
        {
        }

        public override object Convert(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            bool output = (bool)value;
            return !output;
        }

        public override object ConvertBack(
            object value,
            Type targetType,
            object parameter,
            CultureInfo culture)
        {
            bool output = (bool)value;
            return !output;
        }
    }

通过将一个单选按钮绑定到另一个相反的单选按钮来实现。


与其他答案相比,这似乎是一个不太令人满意的hack。 - Mechandrius

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