The following are examples for the PreviewMouseDown method here .
The general convention is that accessing DataGrid.SelectedItem back to its original value inside the DataChanged data handler does not work properly; all code examples that seem to postpone cancellation by asking the dispatcher to schedule it later.
Do you have CellStyle on your datagrid? For me it worked:
XAML:
<DataGrid.CellStyle> <Style TargetType="{x:Type DataGridCell}"> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="Background" Value="DarkSlateBlue"/> <Setter Property="Foreground" Value="White"/> </Trigger> </Style.Triggers> </Style> </DataGrid.CellStyle>
separated code:
private void MyDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (e.AddedItems.Count > 0) { object x = e.AddedItems[0]; if (x is MyObjectType && x != myViewModel.CurrentItem && myViewModel.ShouldNotDeselectCurrentItem()) {
The point is that the SelectedCellsChanged event was fired after the SelectionChanged event - and in particular, that setting the SelectedItem incorrectly updates SelectedCells, which are read-only properties, so there is more codebehind:
private void MyDataGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e) { List<DataGridCellInfo> selectedCells = MyDataGrid.SelectedCells.ToList(); List<MyObjectType> wrongObjects = selectedCells.Select(cellInfo => cellInfo.Item as MyObjectType) .Where (myObject => myObject != myViewModel.CurrentItem).Distinct().ToList(); if (wrongObjects.Count > 0) { MyDataGrid.UnselectAllCells(); MyDataGrid.SelectedItem = null; MyDataGrid.SelectedItem = myViewModel.CurrentItem; } }
Obviously, handlers must connect to the corresponding events in the data grid.
This worked as expected, properly canceling the change of choice, if necessary, and did not flicker.
Js
source share