Como definir / redefinir o valor da caixa de seleção de três estados no WPF

Eu tenho um datagrid cuja uma das colunas do cabeçalho é de três estados. O modelo de célula para essa coluna contém duas caixas de seleção de estado + Caixa de seleção AllItems - Item1 - Item2 - Item3. Eu queria usar a caixa de seleção AllItems para selecionar / desmarcar todos os itens (item1, item2) que funcionam bem. Em seguida, quis definir a caixa de seleção AllItems para o estado intermediário quando nem todos os itens foram selecionados / desmarcados. Da mesma forma, eu queria definir a caixa de seleção AllItems como marcada / desmarcada quando todos os itens fossem selecionados manualmente.

Aqui está o código que eu tentei ...

<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>
...

O método "ItemSelectionCheckBox_Click" procura todos os três estados (todos verificados, não verificados, intermediários) e define a propriedade "IsAllItemChecked", que é INotifyproperty. Não funciona. Outra alternativa que posso tentar é encontrar o elemento "AllItems" e defini-lo a partir do código. Não foi possível localizar nada parecido na web. Existem alguns exemplos, mas é para o TreeView e não da maneira que estou tentando. Qualquer ajuda?

PS >>

Atualizado com correção para fechar esta postagem.

A primeira coisa que eu queria era permitir que "AllItemSelectionCheckBox" tivesse apenas dois estados (True, False) quando selecionado manualmente.

private void AllItemSelectionCheckBox_Click(object sender, RoutedEventArgs e)
{
    var cb = e.Source as CheckBox;
    if (!cb.IsChecked.HasValue)
        cb.IsChecked = false;  
}
Eu queria que a caixa de seleção "AllItemSelectionCheckBox" mostrasse três estados através do código.Todas as caixas de seleção marcadas farão com que seu valor seja TRUETodas as caixas de seleção desmarcadas farão com que seu valor seja FALSEAlguns poucos selecionados farão com que seu valor seja NULL.

Exemplo de código a seguir:

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
    }
}

A atualização de NumberOfItemsChecked count globalmente não funcionou devido à condição de corrida corromper o valor externo.

Nota: O código acima é mais como um exemplo e pode não funcionar copiando-o diretamente. Eu posso fornecer código completo com amostra a pedido.

questionAnswers(3)

yourAnswerToTheQuestion