Row change prevention in datagrid

I researched this and is confused: I have a DataGrid WPF and using the MVVM model. I want, under certain circumstances, to prevent the possibility of changing a row in a DataGrid. I researched this and tried methods like the one found here .

In practice, this works, but there is an unwanted β€œflicker” (it selects the typed line for a moment, and then returns to the previous selection), while this is a close solution, I would like for there to be a more elegant way like preventing the line from changing at all.

I am surprised that there is no SelectionChanging or BeforeSelectionChanged, so I can cancel the event from firing; and forcibly preventing index changes in my view model doesn't seem to make any difference.

How can i do this?

Thanks.

+8
c # wpf datagrid
source share
3 answers

what happens if you take the previewkeydown and previewmousedown and just call e.Handled=true under your specific circumstances?

Edit: to suit the mvvm style: you can create a Behavior with DependencyProperty , with which you can relate your circumstances. in this case you can handle events and maybe some other things, for example, the user clicks on datarow or the title ...

+5
source share

DispatcherPriority is set to ContextIdle. This makes you flicker since your SelectedItem is set twice (and it is displayed twice). Just set the priority to Normal and you will no longer flicker.

+2
source share

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()) { // this will actually revert the SelectedItem correctly, but it won't highlight the correct (old) row. this.MyDataGrid.SelectedItem = null; this.MyDataGrid.SelectedItem = myViewModel.CurrentItem; } } } 

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.

0
source share

All Articles