WPF datagrid поведение как у проводника с checkbox

Есть вот такая грида

<DataGrid Grid.Row="1"                  
              ItemsSource="{Binding Data}"
              SelectionMode="Extended"
              SelectionUnit="FullRow"
              AutoGenerateColumns="False">
        <DataGrid.RowStyle>
            <Style TargetType="DataGridRow">
                <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
            </Style>
        </DataGrid.RowStyle>
        <DataGrid.CellStyle>
            <Style TargetType="DataGridCell">                    
            </Style>
        </DataGrid.CellStyle>
        <DataGrid.Columns>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>                        
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged
                                ,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}} }"/>
                            <TextBlock Text="{Binding Header}"/>
                        </StackPanel>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

Выделение через клик по ячейке работает нормально. А вот клик по чекбоксу не работает. Косяк я так понимаю в том, что сначала обрабатывается клик по ячейке и выставляется свойство IsSelected, а уже потом по чекбоксу и, следовательно, флаг тут же снимается так как IsSelected уже true к этому моменту.

У кого-нибудь есть идеи как это полечить?


Ответы (1 шт):

Автор решения: aepot

У меня не получилось это полечить с помощью стилей, но было очевидно, что Click это RoutedEvent, и чтобы при клике на чекбокс на него не реагировала DataGrid, его надо перехватить, а сделать это можно только с помощью обработчика события, поэтому разметка у меня получилась вот такая:

<DataGrid Grid.Row="1"                  
        ItemsSource="{Binding Data}"
        SelectionMode="Extended"
        SelectionUnit="FullRow"
        AutoGenerateColumns="False">
    <DataGrid.RowStyle>
        <Style TargetType="DataGridRow">
            <Setter Property="IsSelected" Value="{Binding IsSelected}"/>
        </Style>
    </DataGrid.RowStyle>
    <DataGrid.Columns>
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <CheckBox IsChecked="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged}"
                                  PreviewMouseLeftButtonDown="CheckBox_PreviewMouseLeftButtonDown"/>
                        <TextBlock Text="{Binding Header}"/>
                    </StackPanel>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

И вот такой обработчик события в код-бихайнде

private void CheckBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    if (sender is CheckBox checkBox)
        checkBox.IsChecked = !checkBox.IsChecked;
    e.Handled = true;
}

Теперь клик на чекбокс не влияет на выделение строки стредствами DataGrid. Единственный момент, клик на чекбокс теперь еще и не фокусит таблицу, если она не в фокусе, но я думаю, это тоже можно легко проверить и подкорректировать, если оно мешает.

→ Ссылка