WPF Radiobutton(二)(绑定到布尔值)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3361362/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:58:17  来源:igfitidea点击:

WPF Radiobutton (two) (binding to boolean value)

wpfbindingradio-buttonboolean

提问by no9

I have a property of type boolean presented with checkbox.

我有一个带有复选框的布尔类型的属性。

I want to change that to two radiobuttons that bind on the same property presenting the value true/false.

我想将其更改为绑定在同一属性上的两个单选按钮,呈现值真/假。

How can that be done?

那怎么办呢?

回答by Ragunathan

<RadioButton GroupName="Group1" 
             IsChecked="{Binding PropertyValue}" Content="Yes" />
<RadioButton GroupName="Group1"  Content="No" 
             IsChecked="{Binding PropertyValue, 
                         Converter={StaticResource BoolInverterConverter}}" />
public class BoolInverterConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
    {
        if (value is bool)
        {
            return !(bool)value;
        }
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, 
        System.Globalization.CultureInfo culture)
    {
        if (value is bool)
        {
            return !(bool)value;
        }
        return value;
    }

    #endregion
}

回答by RandomEngy

The standard binding approach has the unfortunate side effect of firing the binding setter as "unselected" whenever the UI is loaded. So if you've got code to handle the user's clicks in the setter for your bool, it will do some weird stuff like fire the setter to "false" even though you've bound it to a "true" bool.

标准绑定方法有一个不幸的副作用,就是在加载 UI 时将绑定设置器触发为“未选择”。所以如果你有代码来处理用户在你的 bool 的 setter 中的点击,它会做一些奇怪的事情,比如将 setter 触发为“false”,即使你已经将它绑定到“true”bool。

I got around this with a converter used specifically for radio buttons:

我用一个专门用于单选按钮的转换器解决了这个问题:

public class BoolRadioConverter : IValueConverter
{
    public bool Inverse { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool boolValue = (bool) value;

        return this.Inverse ? !boolValue : boolValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool boolValue = (bool)value;

        if (!boolValue)
        {
            // We only care when the user clicks a radio button to select it.
            return null;
        }

        return !this.Inverse;
    }
}

In your resources:

在您的资源中:

<converters:BoolRadioConverter x:Key="BoolRadioConverter" />
<converters:BoolRadioConverter x:Key="InverseBoolRadioConverter" Inverse="True" />

In your xaml:

在您的 xaml 中:

<RadioButton
    Content="True option"
    GroupName="radioGroup1"
    IsChecked="{Binding MyProperty,
                        Converter={StaticResource BoolRadioConverter}}" />
<RadioButton
    Content="False option"
    GroupName="radioGroup2"
    IsChecked="{Binding MyProperty,
                        Converter={StaticResource InverseBoolRadioConverter}}" />

回答by HCL

You can use a value-converter that reverts the boolean value:

您可以使用值转换器来恢复布尔值:

With that converter, bind one Checkbox.IsChecked-property to the boolean value without the converter and one CheckBox.IsChecked-property with the converter. This should do the trick.

使用该转换器,将一个 Checkbox.IsChecked-property 绑定到没有转换器的布尔值,将一个 CheckBox.IsChecked-property 绑定到带有转换器的布尔值。这应该可以解决问题。

Here the code for such a converter. I have copied it from hereand added some lines of code. There you will find more information about.

这里是这种转换器的代码。我从这里复制了它并添加了一些代码行。在那里你会找到更多的信息。

public class BoolToOppositeBoolConverter : IValueConverter {
    public object Convert(object value, Type targetType, object parameter,System.Globalization.CultureInfo culture) {
        if (targetType != typeof(bool)) {
            throw new InvalidOperationException("The target must be a boolean");
        }
        if (null == value) {
            return null;
        }
                    return !(bool)value;
    }

    public object ConvertBack(object value, Type targetType, object parameter,System.Globalization.CultureInfo culture) {
        if (targetType != typeof(bool)) {
            throw new InvalidOperationException("The target must be a boolean");
        }
        if (null == value) {
            return null;
        }
        return !(bool)value;
    }
} 

To use it, declare it in the resource-section.

要使用它,请在资源部分中声明它。

 <local:BoolToOppositeBoolConverter x:Key="BoolToOppositeBoolConverter_ValueConverter"/>

And the use it in the binding as a static resource:

并在绑定中将其用作静态资源:

<CheckBox IsChecked="{Binding YourProperty}" />
<CheckBox IsChecked="{Binding YourProperty,Converter={StaticResource BoolToOppositeBoolConverter_ValueConverter}}" />

Please note, the converter is only a simple example. Implement it neatly if you want to use it in productive code. I have not tested it. Make a comment if its not working.

请注意,转换器只是一个简单的例子。如果您想在生产代码中使用它,请巧妙地实现它。我没有测试过。如果它不起作用,请发表评论。

回答by votrubac

You can achieve this without a converter if you set the GroupName property of two radio button to the same value (so only one can be checked at the time). Then, set IsChecked of one radio button to "True", and bind IsChecked of another to your Boolean. Switching radio buttons will change the Boolean value, however, changing the Boolean value to False will not check the other radio button.

如果您将两个单选按钮的 GroupName 属性设置为相同的值(因此一次只能检查一个),则无需转换器即可实现此目的。然后,将一个单选按钮的 IsChecked 设置为“True”,并将另一个单选按钮的 IsChecked 绑定到您的布尔值。切换单选按钮将更改布尔值,但是,将布尔值更改为 False 不会检查其他单选按钮。

Thanks, Vlad

谢谢,弗拉德

回答by votrubac

Here is the solution on how to bind radio buttons to any type (enumeration, Boolean, string, integer, etc.) with the sample code:

以下是有关如何使用示例代码将单选按钮绑定到任何类型(枚举、布尔值、字符串、整数等)的解决方案:

http://www.codeproject.com/Tips/720497/Binding-Radio-Buttons-to-a-Single-Property

http://www.codeproject.com/Tips/720497/Binding-Radio-Buttons-to-a-Single-Property

回答by oddRaven

Simplified version of ragunathan's answer.

简化的版本ragunathan答案

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) =>
    Convert(value);

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) =>
    Convert(value);

private object Convert(object value) => 
    value is bool ? !(bool)value : value;

回答by Mr-RandomQC

Little upgrade of RandomEngy's answer if you want your bool nullable (for no default value/Checked Radiobutton)

如果你希望你的 bool 可以为空(没有默认值/选中的单选按钮),那么 RandomEngy 的答案的小升级

public class BoolRadioConverter : IValueConverter
{
    public bool Inverse { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool? boolValue = (bool?)value;

        return this.Inverse ? !boolValue : boolValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool? boolValue = (bool?)value;

        if (boolValue != null && (bool)!boolValue)
        {
            // We only care when the user clicks a radio button to select it.
            return null;
        }

        return !this.Inverse;
    }
}

and the rest is the same as his answer.

其余的和他的回答一样。

回答by Pavel Popov

When using MVVMLightand DataContextis set in XAMLas:

XAML 中使用MVVMLightDataContext设置为:

DataContext="{Binding <Your ViewModel property name>, Source={StaticResource Locator}}" 

BoolInverterConvertercauses Stack Overflowsecond time the window gets opened.

BoolInverterConverter导致Stack Overflow第二次打开窗口。

The work around is to remove DataContextfrom XAML and do it in code in window constructor after InitializeComponent():

解决方法是DataContext从 XAML 中删除并在窗口构造函数中的代码中执行以下操作InitializeComponent()

DataContext = ServiceLocator.Current.GetInstance<Your View Model class>();

After some testing it was not enough - Stack Overflow error could pop up randomly when clicking on radio button. The solution which worked for me - instead of the converter use another property for other radio button in a group:

经过一些测试还不够 - 单击单选按钮时可能会随机弹出堆栈溢出错误。对我有用的解决方案 - 而不是转换器为组中的其他单选按钮使用另一个属性:

public bool Is9to1 { get; set; }
public bool Is1to9 { get { return !Is9to1; } set { Is9to1 = !value; } } 

in XAML:

在 XAML 中:

   <RadioButton GroupName="Is9to1" IsChecked="{Binding Is1to9}"/>
   <RadioButton GroupName="Is9to1" IsChecked="{Binding Is9to1}"/>