防止数据网格中的行更改

我研究了这个并且很难​​过:我有一个WPF DataGrid,并使用MVVM模型。 在某些情况下,我希望阻止更改DataGrid中的行的能力。 我研究了这个,并尝试过像这里找到的技术。

在实践中,这是有效的,但是有一个不受欢迎的’闪烁’(它选择点击的行片刻然后回到之前的选择),而这是一个接近的解决方案我希望有一个更优雅的方式,如防止首先是行改变。

我很惊讶没有SelectionChanging或BeforeSelectionChanged所以我可以取消激活事件; 并强行阻止我的视图模型中的索引更改似乎没有任何区别。

我怎样才能做到这一点?

谢谢。

如果你采取了previewkeydownpreviewmousedown事件,并在你的特定情况下调用e.Handled=true会发生什么?

编辑:满足mvvm样式:您可以使用DependencyProperty创建一个可以绑定环境的Behavior 。 在这种行为中,您可以处理事件以及其他一些事情,例如用户点击数据行或标题…

DispatcherPriority已设置为ContextIdle。 这使您有闪烁,因为您的SelectedItem被设置两次(并且它被渲染两次)。 只需将优先级设置为“正常”,您就不会再闪烁了。

这里有一些PreviewMouseDown方法的示例。

一般协议是将DataGrid.SelectedItem反转回datagrid的SelectionChanged处理程序内的原始值不能按预期工作; 似乎有效的所有代码示例都会通过要求Dispatcher稍后安排它来推迟逆转。

你的数据网格上有CellStyle吗? 对我来说,以下工作:

XAML:

    

代码隐藏:

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

关键是在SelectionChanged事件之后触发了SelectedCellsChanged事件 – 特别是,设置SelectedItem不能正确更新作为只读属性的SelectedCells,因此更多的代码隐藏:

 private void MyDataGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e) { List selectedCells = MyDataGrid.SelectedCells.ToList(); List 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; } } 

显然,处理程序需要连接到数据网格上的相应事件。

这可以像预期的那样工作,如果需要,可以正确取消选择更改,并且不会产生闪烁。