每当DataGrid增加或删除行时,我希望能重新计算一些东西。我尝试使用Loaded
事件,但那只会触发一次。
我找到了AddingNewItem
,但那是在添加之前触发的。我需要在之后执行我的操作。
还有LayoutUpdated
,它可以工作,但我担心使用它不明智,因为它对我的目的来说触发得太频繁了。
每当DataGrid增加或删除行时,我希望能重新计算一些东西。我尝试使用Loaded
事件,但那只会触发一次。
我找到了AddingNewItem
,但那是在添加之前触发的。我需要在之后执行我的操作。
还有LayoutUpdated
,它可以工作,但我担心使用它不明智,因为它对我的目的来说触发得太频繁了。
// 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<ViewModelBase>;
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
。这意味着你的ViewModel
会在绑定的集合更改时广播一个DataCollectionChanged
事件消息,你的View
将订阅接收这些消息,并在其发生时执行代码。
使用EventAggregator
// Subscribe
eventAggregator.GetEvent<CollectionChangedMessage>().Subscribe(DoWork);
// Broadcast
eventAggregator.GetEvent<CollectionChangedMessage>().Publish();
使用 Messenger
//Subscribe
Messenger.Default.Register<CollectionChangedMessage>(DoWork);
// Broadcast
Messenger.Default.Send<CollectionChangedMessage>()
那么 DataGrid.LoadingRow(object sender, DataGridRowEventArgs e)
怎么样?
卸载时同理。
DataGrid.UnLoadingRow(object sender, DataGridRowEventArgs e)
呢?
你尝试过使用MVVM模式并绑定到可观察集合吗?
public ObservableCollection<Thing> Items{
get { return _items; }
set{ _items = value; RaisePropertyChanged("Items"); // Do additional processing here
}
}
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
}
如果您想使用ObservableCollection并获取有关添加或其他操作的通知,则最好使用INotifyCollectionChanged。
var source = datagrid.ItemsSource as INotifyCollectionChanged;
ObservableCollection<MyClass>()
时,你必须强制写 MyClass(而不是 ObservableCollection<ParentOfMyClass>
())。根据您想要重新计算的“事物”,您可以考虑使用ScrollViewer.ScrollChanged附加事件。这可以在XAML中设置如下:
<DataGrid
...
ScrollViewer.ScrollChanged="control_ScrollChanged">
ScrollChangedEventArgs 对象具有多个属性,可用于计算布局和滚动位置(Extent,Offset,Viewport)。请注意,使用默认的虚拟化设置时,这些属性通常以行数/列数为度量单位。
我正在寻找解决方案,我已经找到了处理此问题的完美事件,该事件称为UnloadingRow
<DataGrid ....
UnloadingRow="DataGrid_UnloadingRow">
...
</DataGrid>
在你的 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
}