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 шт):
У меня не получилось это полечить с помощью стилей, но было очевидно, что 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. Единственный момент, клик на чекбокс теперь еще и не фокусит таблицу, если она не в фокусе, но я думаю, это тоже можно легко проверить и подкорректировать, если оно мешает.