簡體   English   中英

添加/刪除行時,WPF DataGrid是否會觸發事件?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM