如何在WPF中设置/重置三态复选框值

sof*_*low 6 wpf checkbox wpf-controls wpfdatagrid

我有一个datagrid,其中一个标题列是三态复选框.该列的celltemplate包含两个状态复选框+ AllItems CheckBox - Item1 - Item2 - Item3 ..我想使用AllItems复选框来选择/取消选择工作正常的所有项目(item1,item2).接下来,我想在未选择/取消选择所有项目时将AllItems复选框设置为中间状态.同样,我想在手动选择所有项目时将AllItems复选框设置为选中/取消选中.

这是我试过的代码......

<dg:DataGridTemplateColumn.HeaderTemplate>
    <DataTemplate>
        <StackPanel x:Name="StackPanelForItemCheckbox" Orientation="Horizontal">
           <CheckBox x:Name="AllItemSelectionCheckBox" HorizontalAlignment="Left" Cursor="Hand"  
                     IsChecked="{Binding IsAllItemChecked, Mode=TwoWay}"                                              
                     IsThreeState="True"  Checked="ItemSelectionCheckBox_Checked" 
                     Unchecked="ItemSelectionCheckBox_Unchecked"
                     Click="AllItemSelectionCheckBox_Click">
           <TextBlock x:Name="ItemNameTextBlock" Text="Item" Margin="10,0,0,0">
           ......
<dg:DataGridTemplateColumn.CellTemplate>
       <DataTemplate x:Name="ItemCheckDataTemplate">                                
           <StackPanel x:Name="ItemCheckBoxStackPanel" Orientation="Horizontal">                                    
                  <CheckBox x:Name="itemCheckBox" Cursor="Hand" IsChecked="{Binding IsItemChecked, Mode=TwoWay}" Click="ItemSelectionCheckBox_Click"></CheckBox>
                   <TextBlock x:Name="ItemNameTextBlock" Text="{Binding Path=Item}"> </TextBlock>                                   
            </StackPanel>
         </DataTemplate>
...
Run Code Online (Sandbox Code Playgroud)

"ItemSelectionCheckBox_Click"方法查找所有三个状态(全部检查,未检查,中间)并设置"IsAllItemChecked"属性,即INotifyproperty.这是行不通的.我可能尝试的其他替代方法是找到"AllItems"元素并从代码中设置它.无法在网络上找到类似的内容.几乎没有例子,但TreeView并不是我尝试的方式.有帮助吗?

PS >>

更新了修复以关闭此帖子.

  • 我想要的第一件事是允许"AllItemSelectionCheckBox"在手动选择时只有两个状态(True,False).

    private void AllItemSelectionCheckBox_Click(object sender, RoutedEventArgs e)
    {
        var cb = e.Source as CheckBox;
        if (!cb.IsChecked.HasValue)
            cb.IsChecked = false;  
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 我想要"AllItemSelectionCheckBox"复选框来显示三态直通代码.
  • 选中所有复选框将使其值为TRUE
  • 未选中所有复选框将导致其值为FALSE
  • 任何少数选定将导致其值为NULL.

代码示例如下:

private void itemCheckBox_Checked(object sender, RoutedEventArgs e)
{ 
    DataGridRowsPresenter DGRPresenter = FindVisualChild<DataGridRowsPresenter>(DataGName1);
    if (DGRP == null || DGRP.Children == null)
        return null;
    foreach (object obj in UIEC)
    {
        DGR = obj as Microsoft.Windows.Controls.DataGridRow;
        UIC = DGR.Item as <datagrid mapped data model>;
        if (DGR.IsSelected == true)
            UIC.IsItemChecked = true;
        if (UIC.IsItemChecked == true)
                NumberOfItemsChecked++;
    }
    if (NumberOfItemsChecked == myViewModelAllItems.Count)
    {
        allcheckbox.IsChecked = true;
    }
    else if (NumberOfItemsChecked < myViewModelAllItems.Count)
    {
        allcheckbox.IsChecked = null;   //intermittent state
    }
}
Run Code Online (Sandbox Code Playgroud)

由于竞争条件破坏了外部值,全局更新NumberOfItemsChecked计数不起作用.

注意:上面的代码更像是一个示例,可能无法直接复制它.我可以根据要求提供完整的代码示例.

Lee*_*ere 14

其实我有一个更好.

我发现如果我为IsThreeState创建一个绑定,然后根据值是否设置更改值,那么它可以工作.

bool? _Value;
public bool? Value
{
    get { return _Value; }
    set
    {
        if (value == null)
        {
            IsThreeState = true;
        }
        else
        {
            IsThreeState = false;
        }
        _Value = value;

        NotifyPropertyChanged("Value");
    }
}

bool _IsThreeState = true;
public bool IsThreeState
{
    get { return _IsThreeState; }
    private set
    {
        _IsThreeState = value;
        NotifyPropertyChanged("IsThreeState");
    }
}
Run Code Online (Sandbox Code Playgroud)

现在该复选框将支持三态IFF,该值在外部设置为null.如果值为true或false,则用户将无法将其设置为null.

  • 小简化:`IsThreeState =!value.HasValue` (2认同)

Ble*_*ose 5

对于想要实现这一目标的人

  • 用户只能将视图中的复选框切换为 true 或 false。不要未定义!
  • ViewModel 中的代码可以将复选框切换为 true 或 false 或未定义

就这样做:

  • 添加复选框以查看但不要设置IsThreeState=true
  • 绑定IsCheckedbool?ViewModel 中的(可为 null bool)属性

null现在,您可以在 ViewModel 中将其设置为,而用户无法在 View 中执行此操作。