WPF Radiobutton(二)(绑定到布尔值)
Posted
技术标签:
【中文标题】WPF Radiobutton(二)(绑定到布尔值)【英文标题】:WPF Radiobutton (two) (binding to boolean value) 【发布时间】:2011-03-22 15:22:34 【问题描述】:我有一个带有复选框的布尔类型属性。
我想将其更改为绑定在相同属性上的两个单选按钮,呈现值 true/false。
如何做到这一点?
【问题讨论】:
【参考方案1】:您可以使用一个值转换器来恢复布尔值:
使用该转换器,将一个 Checkbox.IsChecked-property 绑定到没有转换器的布尔值,并将一个 CheckBox.IsChecked-property 与转换器绑定。这应该可以解决问题。
这里是这种转换器的代码。我从here 复制了它并添加了一些代码行。在那里你会找到更多的信息。
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;
要使用它,请在资源部分中声明它。
<local:BoolToOppositeBoolConverter x:Key="BoolToOppositeBoolConverter_ValueConverter"/>
并且在绑定中使用它作为静态资源:
<CheckBox IsChecked="Binding YourProperty" />
<CheckBox IsChecked="Binding YourProperty,Converter=StaticResource BoolToOppositeBoolConverter_ValueConverter" />
请注意,转换器只是一个简单的例子。如果您想在生产代码中使用它,请巧妙地实现它。我还没有测试过。如果它不起作用,请发表评论。
【讨论】:
谢谢!我使用过 Ragunathan 解决方案,但两者都很好用。特别感谢您的解释和投入的时间。慢慢地我在 WPF 中挖掘我的方式......【参考方案2】:<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
【讨论】:
出于某种原因,我必须使用两个不同的 GroupName。否则,可以将 ViewModel 中的布尔值设置为 true,但永远不会重置为 false(即使单选按钮看起来正常) 您好,您忘记用“/”关闭第二个单选按钮了。 @Ragunathan 我收到一个错误:“资源 'BoolInverterConverter' 无法解析”。不知道如何解决这个问题:有什么想法吗? @BKSpureon:你只需要添加一个资源部分 我把它放在子窗口中。当我第一次打开子窗口时,它很好。当我第二次关闭并打开子窗口时,由于转换器执行了无数次,因此出现堆栈溢出异常。【参考方案3】:如果您将两个单选按钮的 GroupName 属性设置为相同的值,则无需转换器即可实现此目的(因此当时只能检查一个)。然后,将一个单选按钮的 IsChecked 设置为“True”,并将另一个单选按钮的 IsChecked 绑定到您的布尔值。切换单选按钮会更改布尔值,但是,将布尔值更改为 False 不会检查其他单选按钮。
谢谢, 弗拉德
【讨论】:
如果您多次显示对话框,此方法会产生间歇性绑定副作用。我可以通过在关闭对话框之前清理 Data Context 属性来解决它,所以对我来说它看起来像是一个框架问题。无论如何,我想出了一个更好的解决方案,它支持布尔和枚举,并且无论 GroupName 属性是否设置都可以正常工作。【参考方案4】:下面是如何通过示例代码将单选按钮绑定到任何类型(枚举、布尔值、字符串、整数等)的解决方案:
http://www.codeproject.com/Tips/720497/Binding-Radio-Buttons-to-a-Single-Property
【讨论】:
【参考方案5】:标准绑定方法有一个不幸的副作用,即在加载 UI 时将绑定设置器触发为“未选择”。因此,如果您有代码来处理用户在 bool 的 setter 中的点击,即使您已将 setter 绑定到“true”布尔值,它也会做一些奇怪的事情,例如将 setter 设置为“false”。
我使用专门用于单选按钮的转换器解决了这个问题:
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;
在您的资源中:
<converters:BoolRadioConverter x:Key="BoolRadioConverter" />
<converters:BoolRadioConverter x:Key="InverseBoolRadioConverter" Inverse="True" />
在您的 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" />
【讨论】:
太棒了!对我的问题按预期工作。复制到我的博客以供将来参考 如果我称它为InverseBoolRadioConverter
,我可以忽略 Inverse 变量,并返回 true,因为我总是将它用作单选按钮的转换器。
我发现您的代码最适用于可为空的布尔值,但您可以调整转换器中的 if 条件以处理不可为空: if (!boolValue && Nullable.GetUnderlyingType(targetType) != null )
谢谢!面临同样的问题,很高兴我找到了您的解决方案
当我认识到单选按钮需要位于不同的组时,对我来说效果很好。【参考方案6】:
ragunathan 的answer 的简化版。
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;
【讨论】:
【参考方案7】:如果您希望 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;
其余的和他的回答一样。
【讨论】:
【参考方案8】:当使用 MVVMLight
和 DataContext
在 XAML 中设置为:
DataContext="Binding <Your ViewModel property name>, Source=StaticResource Locator"
BoolInverterConverter
导致 Stack Overflow
第二次打开窗口。
解决方法是从 XAML 中删除 DataContext
,并在 InitializeComponent()
之后的窗口构造函数中的代码中执行此操作:
DataContext = ServiceLocator.Current.GetInstance<Your View Model class>();
经过一些测试,这还不够 - 单击单选按钮时可能会随机弹出 Stack Overflow 错误。对我有用的解决方案 - 而不是转换器,而是为组中的其他单选按钮使用另一个属性:
public bool Is9to1 get; set;
public bool Is1to9 get return !Is9to1; set Is9to1 = !value;
在 XAML 中:
<RadioButton GroupName="Is9to1" IsChecked="Binding Is1to9"/>
<RadioButton GroupName="Is9to1" IsChecked="Binding Is9to1"/>
【讨论】:
这里有同样的问题。我对 WPF 很陌生,所以我停止研究为什么会发生这种情况。最后,我在 XAML 中使用带有CommandParameter
的自定义转换器来避免 SOE。例如。 Yes
选项与CommandParameter=1
,No
选项与CommandParameter=2
以上是关于WPF Radiobutton(二)(绑定到布尔值)的主要内容,如果未能解决你的问题,请参考以下文章
WPF + MVVM + RadioButton:使用单个属性处理绑定
WPF MVVM从入门到精通6:RadioButton等一对多控件的绑定