带有3个状态的复选框,它将在WPF中充当“全选/取消全选”

时间:2013-03-22 13:45:18

标签: wpf data-binding checkbox

我有一个带有几个复选框的WPF窗口,这些复选框被数据化为我对象中相应的布尔属性。我从INotifyPropertyChanged派生了我的对象,因此数据的变化反映在视图中,视图中的变化反映在数据中。

现在我必须添加另一个带有3个状态的复选框,这些状态将作为“全部选择/取消全选”并按以下方式工作:

  • 如果用户选中 - 将检查所有其他复选框
  • 如果用户取消选中 - 将取消选中所有其他复选框
  • 如果选中所有其他复选框 - 将显示为已选中
  • 如果取消选中所有其他复选框,则会显示为未选中
  • 如果选中其他一些复选框 - 将显示为不确定

我是WPF的新手。我怎么能在WPF中做到这一点?

1 个答案:

答案 0 :(得分:1)

我确信有更好的方法可以解决这个问题,但这是我提出的一个快速解决方案,似乎工作正常。

这是XAML:

<Window x:Class="StackOverflow.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:StackOverflow"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:AllNoneCheckboxConverter x:Key="converter"/>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <CheckBox x:Name="chk1" Content="1"/>
            <CheckBox x:Name="chk2" Content="2"/>
            <CheckBox x:Name="chk3" Content="3"/>
            <CheckBox x:Name="all" Content="all">
                <CheckBox.IsChecked>
                    <MultiBinding Converter="{StaticResource converter}">
                        <Binding ElementName="chk1" Path="IsChecked"/>
                        <Binding ElementName="chk2" Path="IsChecked"/>
                        <Binding ElementName="chk3" Path="IsChecked"/>
                    </MultiBinding>
                </CheckBox.IsChecked>
            </CheckBox>
        </StackPanel>
    </Grid>
</Window>

这是MultiValueConverter;

class AllNoneCheckboxConverter: IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool result = (bool)values[0];
            for (int i = 0; i < values.Length; i++)
                if (result != (bool)values[i])
                    return null;

            return result;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            object[] result = new object[targetTypes.Length];
            bool isChecked = (bool)value;

            for (int i = 0; i < result.Length; i++)
                if (isChecked)
                    result[i] = true;
                else
                    result[i] = false;

            return result;
        }
    }