c# - 将两个复选框绑定(bind)到 MVVM 中的可为 null 的 bool 属性

标签 c# wpf mvvm

我尝试将两个复选框连接到我的 ViewModel。它们的行为就像单选按钮(独占)和 TheeState。所以两个都没有检查或者其中一个检查

目前我正在做这样的工作:

                            <dxlc:LayoutGroup>
                                <dxlc:LayoutItem Label="with errors">
                                    <CheckBox IsChecked="{Binding OnlyMusicWithErrorsChecked}"></CheckBox>
                                </dxlc:LayoutItem>
                                <dxlc:LayoutItem Label="without errors">
                                    <CheckBox IsChecked="{Binding OnlyMusicWithoutErrorsChecked}"></CheckBox>
                                </dxlc:LayoutItem>
                            </dxlc:LayoutGroup>

和 View 模型:

    private bool _onlyMusicWithErrorsChecked;

    public bool OnlyMusicWithErrorsChecked
    {
        get { return _onlyMusicWithErrorsChecked; }
        set
        {
            SetProperty(ref _onlyMusicWithErrorsChecked, value, () => OnlyMusicWithErrorsChecked);
            if (OnlyMusicWithErrorsChecked)
                OnlyMusicWithoutErrorsChecked = false;
            RaisePropertyChanged("AdditionalCriteriaHeader");
            if (!_filteringData) 
                SelectData();
        }
    }

    private bool _onlyMusicWithoutErrorsChecked;

    public bool OnlyMusicWithoutErrorsChecked
    {
        get { return _onlyMusicWithoutErrorsChecked; }
        set
        {
            SetProperty(ref _onlyMusicWithoutErrorsChecked, value, () => OnlyMusicWithoutErrorsChecked);
            if (OnlyMusicWithoutErrorsChecked)
                OnlyMusicWithErrorsChecked = false;
            RaisePropertyChanged("AdditionalCriteriaHeader");
            if (!_filteringData) 
                SelectData();
        }
    }

问题是:我可以只使用一个属性 nullable bool 来完成这项工作吗?

最佳答案

您可以将两个 CheckBox 绑定(bind)到相同的属性 OnlyMusicWithErrorsChecked,并在第二个 CheckBox 中添加一个反转属性值的转换器:

<CheckBox IsChecked="{Binding OnlyMusicWithErrorsChecked, Converter={StaticResource Inverter}}"></CheckBox>

这个转换器看起来有点像:

public class Inverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is bool)
            return !((bool)value);
        else // Fallback
            return false;
    }
}

编辑:如果您想构建一个只有一个可绑定(bind)属性的三态解决方案,您将需要两个转换器(或一个可以参数化的转换器):

public class MyConverter : DependencyObject, IValueConverter
{
    public static readonly DependencyProperty InvertProperty = DependencyProperty.Register(
        "Invert", typeof (bool), typeof (MyConverter), new PropertyMetadata(default(bool)));

    public bool Invert
    {
        get { return (bool) GetValue(InvertProperty); }
        set { SetValue(InvertProperty, value); }
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var val = (bool?) value;
        switch (val)
        {
            case true:
                return Invert;
                break;
            case false:
                return !Invert;
                break;
            case null:
                return false; // None of the checkboxes shall be active
                break;
        }
        // Fallback
        return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var val = (bool)value;
        switch (val)
        {
            case true:
                return Invert;
                break;
            case false:
                return null;
                break;
        }
        // Fallback
        return false;
    }
}

第一个复选框的 Invert 属性设置为 false,第二个复选框设置为 true:

<Window.Resources>
    <local:MyConverter x:Key="Converter" Invert="False"/>
    <local:MyConverter x:Key="Inverter" Invert="True"/>
</Window.Resources>

现在您可以使用这两个转换器实例将复选框绑定(bind)到相同的属性:

<CheckBox IsChecked="{Binding MyProperty, Converter={StaticResource Converter}}" />
<CheckBox IsChecked="{Binding MyProperty, Converter={StaticResource Inverter}}" />

如果选中第一个框,属性将为 false,如果选中第二个,则为 true,如果没有选中复选框,则为

不过,我同意 ANewGuyInTown 的观点,你最好使用 Enum,因为 bool 类型在这里有点困惑(顺便说一句,大多数在使用三态枚举而不是可空 bool 值时,可以重新使用转换器。

关于c# - 将两个复选框绑定(bind)到 MVVM 中的可为 null 的 bool 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29646499/

相关文章:

c# - 工作框架;在代码隐藏中在路径标记语法和几何图形之间转换

wpf - FlowDocument 重复表头

c# - 阻止 TreeView 中的自动水平滚动不起作用。 MVVM、XAML 方法

c# - 将 C++ 字符串发送到 C# 字符串。互操作性

c# - 如何强制注销网站的所有用户?

c# - 将泛型与可能是值或引用类型的 null 进行比较?

c# - 手动设置组合框项目时如何使用mvvm中的绑定(bind)在wpf中设置组合框默认值

c# - 将 Azure AD 身份验证添加到项目失败 : System. Runtime.InteropServices.COMException

Wpf:拖放到文本框

c# - MVVM Light Toolkit 的文档/示例?