我有一个数据网格,其中一个表头列是三态复选框。该列的单元格模板包含两个状态的复选框: + 全部项目的复选框 - 项目1 - 项目2 - 项目3 .. 我想使用“全部项目”复选框来选择/取消选择所有项目(项目1、项目2),这个功能可以正常工作。接下来,我想在没有全部选择/取消选择所有项目时将“全部项目”复选框设置为中间状态。同样地,当手动选择所有项目时,我想将“全部项目”复选框设置为已选/未选。
以下是我尝试过的代码...
<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>
...
"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;
}
以下是示例代码:
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
}
}
全局更新NumberOfItemsChecked计数器由于竞态条件损坏了外部值。
注意:以上代码更像是一个示例,直接复制可能无法工作。如果需要,我可以提供完整的代码和样本。
IsThreeState = !value.HasValue
可以翻译为“如果value没有值,则IsThreeState为真”。 - Dave Mackersie