[英]Does WPF DataGrid fire an event when a row is added / removed?
我希望每次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<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
。 這意味着DataCollectionChanged
綁定集合發生更改, 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方法並綁定到Observable集合?
public ObservableCollection<Thing> Items{
get { return _items; }
set{ _items = value; RaisePropertyChanged("Items"); // Do additional processing here
}
}
那么您可以在不與UI綁定的情況下觀看項目的添加/刪除嗎?
如果要使用ObservableCollection並獲取有關添加或其他操作的通知,最好使用INotifyCollectionChanged
var source = datagrid.ItemsSource as INotifyCollectionChanged;
因為,當您打開ObservableCollection<MyClass>()
,必須編寫strogly MyClass(不是ObservableCollection<ParentOfMyClass>
())
如果你想要你可以像其他人在這里描述的那樣沿着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中設置如下:
<DataGrid
...
ScrollViewer.ScrollChanged="control_ScrollChanged">
ScrollChangedEventArgs對象具有各種屬性,可用於計算布局和滾動位置(范圍,偏移,視口)。 請注意,這些通常使用默認虛擬化設置時以行/列數量來衡量。
我一直在尋找解決方案,我找到了完美的事件來處理這個事件,這個事件叫做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
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.