【问题标题】:checkbox with 3 states which will act as 'Select all / Unselect all' in WPF具有 3 个状态的复选框,将在 WPF 中充当“全选/取消全选”
【发布时间】:2013-03-22 13:45:18
【问题描述】:

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

现在我必须添加另一个具有 3 个状态的复选框,该复选框将充当“全选/取消全选”,工作如下:

  • 如果用户选中 - 将选中所有其他复选框
  • 如果用户未选中 - 将取消选中所有其他复选框
  • 如果所有其他复选框都被选中 - 将显示为选中
  • 如果所有其他复选框均未选中 - 将显示为未选中
  • 如果其他一些复选框被选中 - 将显示为不确定

我是 WPF 的新手。如何在 WPF 中做到这一点?

【问题讨论】:

    标签: wpf data-binding checkbox


    【解决方案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;
            }
        }
    

    【讨论】:

    • 感谢您的解决方案。必须在 'ConvertBack' 方法中犯一个小错误,因为 'isChecked' 的类型是 bool?,并且还为 'all' 复选框实现了 'click' 事件
    • 我可能误解了您的评论,但我不需要做任何一个来使解决方案发挥作用。您熟悉数据绑定和转换器吗?您绝对不需要为 click 事件实现处理程序。我不确定为什么您需要使用可为空的布尔值进行转换,“全部”复选框只能在单击时将 IsChecked 设置为 true 或 false。
    • 我再次查看它,发现我已将“所有”复选框定义为“IsThreeState="True"”,而您没有。我认为这就是我在 ConvertBack 方法上遇到异常的原因,这就是我对该方法进行更改的原因。我已将我的代码修改为与您的完全相同,并且可以正常工作,尽管我仍然不明白为什么我不需要将“all”复选框的“IsThreeState”属性定义为“True”。
    猜你喜欢
    • 2016-02-20
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 2011-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多