WPF:复选框选中所有其他复选框并取消选中,视觉差异

时间:2015-10-29 15:17:07

标签: wpf

我的应用程序有一些自定义复选框设计,下面是它们的图像。应该很清楚,但是前面的第一个是style1(所有都被检查)。

第二个只是一个复选框,让我们说style2。

但是第三个问题已经让我们说了style3,因为这会显示其中一些子复选框被选中但不是全部,单击此选项将取消选中/检查它们。

我有两个问题。

  1. 有没有办法只使用XAML将这些复选框绑定在一起,这样就有一个主复选框可以取消选中并检查它的子项,还是我必须使用C#命令?

  2. 这是一个主要的问题,当选中所有复选框并且只检查一些复选框时,为主复选框提供不同样式的最佳方法是什么?

  3. enter image description here

1 个答案:

答案 0 :(得分:0)

首先 - 是的,您可以使用MultiBinding。 第二 - 如果你有3个checkBox样式(第一个用于allChecked,第二个用于allunchecked,第三个用于一些已检查和一些未经检查),你可以编写一个样式,将其他人与触发器联合,分配给IsChecked属性。 我为你写了一些例子。

<StackPanel>
    <CheckBox Name="cb1" IsChecked="{Binding Is1}" />
    <CheckBox Name="cb2" IsChecked="{Binding Is2}" />
    <CheckBox Name="cb3" IsChecked="{Binding Is3}" />
    <CheckBox Name="cbMaster" Content="Master">
        <CheckBox.Resources>
            <local:CheckBoxConverter x:Key="cbConv" />
        </CheckBox.Resources>
        <CheckBox.IsChecked>
            <MultiBinding Converter="{StaticResource cbConv}">
                <Binding Path="Is1" />
                <Binding Path="Is2" />
                <Binding Path="Is3" />
            </MultiBinding>
        </CheckBox.IsChecked>
        <CheckBox.Style>
            <Style TargetType="CheckBox">
                <Style.Triggers>
                    <Trigger Property="IsChecked" Value="{x:Null}">
                        <Setter Property="Foreground" Value="Red" />
                    </Trigger>
                    <Trigger Property="IsChecked" Value="true">
                        <Setter Property="Foreground" Value="Green" />
                    </Trigger>
                    <Trigger Property="IsChecked" Value="false">
                        <Setter Property="Foreground" Value="Black" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </CheckBox.Style>
    </CheckBox>
</StackPanel>

转换器就是这样。

public class CheckBoxConverter : IMultiValueConverter
{
    public object Convert( object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture )
    {
        bool isChecked = values.Contains( true );
        bool isUnchecked = values.Contains( false );
        if ( isChecked && isUnchecked )
        {
            // some checked and uncheked
            return null;
        }
        else if ( isChecked )
        {
            return true;
        }
        return false;
    }

    public object[] ConvertBack( object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture )
    {
        int count = targetTypes.Length;
        object[] result = new object[count];
        if ( ( bool )value == true )
        {
            for ( int i = 0; i < count; i++ )
            {
                result[i] = true;
            }
        }
        else
        {
            for ( int i = 0; i < count; i++ )
            {
                result[i] = false;
            }
        }
        return result;
    }
}

ViewModel看起来就是这样。

public class CheckBoxViewModel : INotifyPropertyChanged
{
    private bool _is1;
    public bool Is1
    {
        get { return _is1; }
        set { _is1 = value; NotifyPropertyChanged( "Is1" ); }
    }
    ...
}