WPF DataGrid:使用MVVM干净利落地处理CanUserAddRows = true

时间:2010-11-05 13:04:57

标签: c# wpf mvvm datagrid caliburn.micro

我最近一直在研究MVVM,在我发现Caliburn.Micro之后,事情已经相当迅速;我还处于早期学习阶段,但我相信我对MVVM基础知识有一种感觉。

我遇到了WPF DataGrid的问题 - 而且它与WinForms DataGridView几乎是same issues:你如何处理{{1}网格项目干净利落地添加?

我显然不希望将CanUserAddRows=true特定的黑客添加到我的ViewModel,因为理想情况下应该可以重新用于其他DataGrid控件。同时,我希望能够在添加新的项时收到通知,这样我就可以立即保留它。

我将View绑定到DataGrid - 使用干净的MVVM设计,如果我理解正确,我将能够处理BindableCollection<FooModel> FooItems并对添加/删除作出反应事件。但是,只要添加了默认构造的项目,FooItems.CollectionChanged就会触发Add事件 - 显然是保留对象的正确时间!

经过大量的谷歌搜索和挖掘StackOverflow后,我得到的结论是DataGrid在触发添加/删除事件的过程中完全被延迟了。与DataGrid一起使用它的人似乎只在内存集合中工作,持久数据的人似乎使用单独的输入字段+ 按钮命令来添加新项目。

我的CanUserAddRows=true实现FooModel但不是INotifyPropertyChanged - 据我所知,这应该不是问题,因为IEO似乎与属性编辑/撤消相关,而我的问题是在何时触发Add事件......

那么,您如何处理网格编辑干净利落

2 个答案:

答案 0 :(得分:2)

听起来WPF DataGrid的行为与WinForms DataGridView大致相同,因为一旦用户开始进入“新行”,它就会在数据源中创建一个项目”。后续编辑将导致更改集合中新项目的属性。

如果您改为使用BindingList<FooModel>,则会收到名为ListChanged的其他事件 - 提供您的FooModel类型实现INotifyPropertyChanged,该事件将在项目已更改(以及在集合中添加/删除项目时)。

希望这有帮助!

答案 1 :(得分:0)

我知道已经有很长一段时间了,但是我现在正在研究类似的事情并且认为我会发布我的解决方案。您可能会认为这是一个黑客攻击,但这是我想要让DataGrid告诉我它何时退出编辑模式的最佳方式(出于我自己的原因)。

我查看了DataGrid代码并找到了最接近结束编辑的东西,我可以覆盖,结果是OnExecutedCommitEdit()。然后我在该函数完成后才举起一个事件。当我的事件订阅者被调用时,DataGrid不再处于编辑模式,我可以做任何我需要的事情。这是代码:

/// <summary>
/// Deriving a new DataGrid because we need an event to tell us when editing is complete.
/// </summary>
public class DataGridMod : DataGrid
{
   public delegate void EditCompletedDelegate();
   public EditCompletedDelegate EditCompleted;

   public DataGridMod() { }

   protected override void OnExecutedCommitEdit(ExecutedRoutedEventArgs e)
   {
      base.OnExecutedCommitEdit(e);

      if (EditCompleted != null)
         EditCompleted();
   }
}