9

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

我找到AddingNewItem了,但是在添加之前就被解雇了。之后我需要做我的事情

还有LayoutUpdated,它可以工作,但我担心使用它是不明智的,因为它太频繁地触发我的目的。

4

7 回答 7

11

如果你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 PrismEventAggregator或 MVVM Light 的Messenger. 这意味着您将在绑定集合更改时ViewModel广播事件消息,并且您将订阅以接收这些消息并在它们发生时执行您的代码。DataCollectionChangedView

使用EventAggregator

// Subscribe
eventAggregator.GetEvent<CollectionChangedMessage>().Subscribe(DoWork);

// Broadcast
eventAggregator.GetEvent<CollectionChangedMessage>().Publish();

使用Messenger

//Subscribe
Messenger.Default.Register<CollectionChangedMessage>(DoWork);

// Broadcast
Messenger.Default.Send<CollectionChangedMessage>()
于 2012-07-02T14:04:04.150 回答
2

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

卸载也一样。

DataGrid.UnLoadingRow(object sender, DataGridRowEventArgs e)?

于 2012-07-02T12:24:41.187 回答
2

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

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

所以你可以在不受 UI 约束的情况下观看项目的添加/删除?

于 2012-07-02T14:07:36.580 回答
1

如果您愿意,您可以RowUnloading按照其他人在此处描述的路线走,但是请注意,每次一行失去焦点时也会触发此事件。

但是,通过玩耍,我发现当删除一行时SelectedItem,网格的属性为空,而该CurrentItem属性不为空,到目前为止,我只看到这个组合用于删除的行,(虽然我不能保证我有没有错过一个异国情调的情况......但是对于远离行的基本情况,我到目前为止还没有看到它)。

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

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
}
于 2018-05-30T04:14:41.663 回答
0

如果您想使用 ObservableCollection 并获得有关添加或其他操作的通知,最好的方法是使用 INotifyCollectionChanged

var source = datagrid.ItemsSource as INotifyCollectionChanged;

因为,当你解包到 时ObservableCollection<MyClass>(),你必须严格地写 MyClass (not ObservableCollection<ParentOfMyClass>())

于 2015-06-26T15:13:08.087 回答
-1

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

<DataGrid
...
ScrollViewer.ScrollChanged="control_ScrollChanged">

ScrollChangedEventArgs对象具有有助于计算布局和滚动位置(Extent、Offset、Viewport)的各种属性。请注意,在使用默认虚拟化设置时,这些通常以行数/列数来衡量。

于 2015-10-09T19:00:51.020 回答
-1

我一直在寻找解决方案,我找到了处理这个问题的完美事件,该事件称为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

}
于 2017-01-15T23:07:25.527 回答