更改 DataGrid.ItemsSource 时如何引发事件

Posted

技术标签:

【中文标题】更改 DataGrid.ItemsSource 时如何引发事件【英文标题】:How to raise an event when DataGrid.ItemsSource is changed 【发布时间】:2012-05-29 08:15:18 【问题描述】:

我是 WPF 的新手,我正在使用 DataGrids,我需要知道何时更改属性 ItemsSource。

例如,我需要在执行这条指令时触发一个事件:

dataGrid.ItemsSource = table.DefaultView;

或者当添加一行时。

我已尝试使用此代码:

CollectionView myCollectionView = (CollectionView)CollectionViewSource.GetDefaultView(myGrid.Items);
((INotifyCollectionChanged)myCollectionView).CollectionChanged += new NotifyCollectionChangedEventHandler(DataGrid_CollectionChanged); 

但此代码仅在用户向集合中添加新行时才有效。因此,我需要在整个 ItemsSource 属性发生任何更改时引发一个事件,无论是因为替换了整个集合还是添加了单行。

我希望你能帮助我。提前谢谢你

【问题讨论】:

你看过 row_Created 事件吗? 【参考方案1】:

ItemsSource 是一个依赖属性,因此当属性更改为其他内容时很容易收到通知。除了您拥有的代码之外,您还想使用它,而不是:

Window.Loaded(或类似的)中,您可以像这样订阅:

var dpd = DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, typeof(DataGrid));
if (dpd != null)

    dpd.AddValueChanged(myGrid, ThisIsCalledWhenPropertyIsChanged);

并且有一个变更处理程序:

private void ThisIsCalledWhenPropertyIsChanged(object sender, EventArgs e)


只要设置了ItemsSource 属性,就会调用ThisIsCalledWhenPropertyIsChanged 方法。

您可以将它用于任何希望收到更改通知的依赖项属性。

【讨论】:

非常好!正是我想要的。 如果继承自标准控件,则允许创建良好的控件行为! 要记住的一点是,如果不明确删除,这种模式会造成严重的内存泄漏。源对象(此答案中的myGrid)永远不会被垃圾收集,因为静态DependencyPropertyDescriptor 在应用程序的整个生命周期内都对其具有强引用。 See this question for details【参考方案2】:

这有帮助吗?

public class MyDataGrid : DataGrid

    protected override void OnItemsSourceChanged(
                                    IEnumerable oldValue, IEnumerable newValue)
    
        base.OnItemsSourceChanged(oldValue, newValue);

        // do something here?
    

    protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
    
        base.OnItemsChanged(e);

        switch (e.Action)
        
            case NotifyCollectionChangedAction.Add:
                break;
            case NotifyCollectionChangedAction.Remove:
                break;
            case NotifyCollectionChangedAction.Replace:
                break;
            case NotifyCollectionChangedAction.Move:
                break;
            case NotifyCollectionChangedAction.Reset:
                break;
            default:
                throw new ArgumentOutOfRangeException();
        
    

【讨论】:

【参考方案3】:

如果您想检测添加的新行,可以尝试 DataGrid 的 InitializingNewItemAddingNewItem 事件。

InitializingNewItem 用法:

Datagrid auto add item with data of parent

【讨论】:

以上是关于更改 DataGrid.ItemsSource 时如何引发事件的主要内容,如果未能解决你的问题,请参考以下文章

wpf中,当DataGrid.ItemsSource与ObservableCollection绑定后,值变化时,DataGrid如何刷新?

WPF DataGrid ItemsSource 内存泄漏

在XAML代码中绑定数据时,WPF DataGrid ItemsSource绑定不显示数据

DataTable 作为 DataGrid.ItemsSource

如何将 DataGridTemplateColumn.Visibility 绑定到 DataGrid.ItemsSource 之外的属性?

WPF DataGrid MultiBinding到DataGrid ItemSsource中的类