添加/删除行时,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 }