添加/删除行时,WPF DataGrid是否会触发事件?

我希望每次DataGrid获取更多行或删除一些行时重新计算事物。 我尝试使用Loaded事件,但只触发了一次。

我找到了AddingNewItem ,但是在添加它之前就已经触发了。 之后我需要做我的事情。

还有LayoutUpdated ,它有效,但我担心使用它是不明智的,因为它经常为我的目的而激发。

如果您的DataGrid绑定了某些东西,我想到了两种方法。

您可以尝试获取DataGrid.ItemsSource集合,并订阅其CollectionChanged事件。 这只有在你知道它首先是什么类型的集合时才有效。

 // Be warned that the `Loaded` event runs anytime the window loads into view, // so you will probably want to include an Unloaded event that detaches the // collection private void DataGrid_Loaded(object sender, RoutedEventArgs e) { var dg = (DataGrid)sender; if (dg == null || dg.ItemsSource == null) return; var sourceCollection = dg.ItemsSource as ObservableCollection; if (sourceCollection == null) return; sourceCollection .CollectionChanged += new NotifyCollectionChangedEventHandler(DataGrid_CollectionChanged); } void DataGrid_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { // Execute your logic here } 

另一种解决方案是使用事件系统,如Microsoft Prism的EventAggregator或MVVM Light的Messenger 。 这意味着DataCollectionChanged绑定集合发生更改, ViewModel就会广播DataCollectionChanged事件消息,并且View会订阅接收这些消息并在任何时候执行代码。

使用EventAggregator

 // Subscribe eventAggregator.GetEvent().Subscribe(DoWork); // Broadcast eventAggregator.GetEvent().Publish(); 

使用Messenger

 //Subscribe Messenger.Default.Register(DoWork); // Broadcast Messenger.Default.Send() 

DataGrid.LoadingRow(object sender, DataGridRowEventArgs e)怎么样?

卸载相同。

DataGrid.UnLoadingRow(object sender, DataGridRowEventArgs e)

您是否尝试过MVVM方法并绑定到Observable集合?

 public ObservableCollection Items{ get { return _items; } set{ _items = value; RaisePropertyChanged("Items"); // Do additional processing here } } 

那么您可以在不与UI绑定的情况下观看项目的添加/删除吗?

如果要使用ObservableCollection并获取有关添加或其他操作的通知,最好使用INotifyCollectionChanged

 var source = datagrid.ItemsSource as INotifyCollectionChanged; 

因为,当您打开ObservableCollection() ,必须编写strogly MyClass(不是ObservableCollection ())

如果你想要,你可以像其他人在这里描述的那样沿着RowUnloading路线RowUnloading ,但请注意,每当一行失去焦点时,此事件也会触发。

然而,通过玩游戏,我发现当删除一行时,网格的SelectedItem属性为null,而CurrentItem属性不为null,到目前为止,我已经看到这个组合仅用于已删除的行,(尽管我无法保证我没有错过异国情调……但是对于离开排的基本情况我到目前为止还没有看到它)。

因此,何时可以使用以下代码仅过滤已删除的行:

 private void CategoriesGrid_UnloadingRow(object sender, DataGridRowEventArgs e) { if (((DataGrid)sender).SelectedItem != null || ((DataGrid)sender).CurrentItem == null) { return; } // The rest of your code goes here } 

根据您要重新计算的“事物”,您可以考虑使用ScrollViewer.ScrollChanged附加事件。 这可以在XAML中设置如下:

  

ScrollChangedEventArgs对象具有各种属性,可用于计算布局和滚动位置(范围,偏移,视口)。 请注意,使用默认虚拟化设置时,通常会以行/列数来衡量这些值。

我一直在寻找解决方案,我找到了完美的事件来处理这个事件,这个事件叫做UnloadingRow

  ...  

在你的C#代码中你得到这个

 private void ProductsDataGrid_UnloadingRow(object sender, DataGridRowEventArgs e) { MyObject obj = (MyObject)e.Row.Item; // get the deleted item to handle it // Rest of your code ... // For example : deleting the object from DB using entityframework }