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

Dan*_*nte 28 c# wpf events datagrid

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

例如,我需要在执行此指令时必须引发事件:

dataGrid.ItemsSource = table.DefaultView;
Run Code Online (Sandbox Code Playgroud)

或者添加行时.

我试过使用这段代码:

CollectionView myCollectionView = (CollectionView)CollectionViewSource.GetDefaultView(myGrid.Items);
((INotifyCollectionChanged)myCollectionView).CollectionChanged += new NotifyCollectionChangedEventHandler(DataGrid_CollectionChanged); 
Run Code Online (Sandbox Code Playgroud)

但此代码仅在用户向集合添加新行时才有效.因此,当整个ItemsSource属性发生任何更改时,我需要引发一个事件,因为整个集合被替换或者因为添加了一行.

我希望你能帮助我.先感谢您

vcs*_*nes 59

ItemsSource是一个依赖属性,因此当属性更改为其他属性时,通知很容易.除了代码之外,你还想使用它,而不是:

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

var dpd = DependencyPropertyDescriptor.FromProperty(ItemsControl.ItemsSourceProperty, typeof(DataGrid));
if (dpd != null)
{
    dpd.AddValueChanged(myGrid, ThisIsCalledWhenPropertyIsChanged);
}
Run Code Online (Sandbox Code Playgroud)

并有一个更改处理程序:

private void ThisIsCalledWhenPropertyIsChanged(object sender, EventArgs e)
{
}
Run Code Online (Sandbox Code Playgroud)

只要ItemsSource设置了Property,ThisIsCalledWhenPropertyIsChanged就会调用该方法.

您可以将此用于要通知更改的任何依赖项属性.

  • 非常好!正是我在寻找什么. (3认同)
  • 要记住的一件事是,如果没有明确删除,这种模式会造成错误的内存泄漏.源对象(在这个答案中的`myGrid`)永远不会被垃圾收集,因为静态`DependencyPropertyDescriptor`在应用程序的生命周期中拥有对它的强引用.[详情请参阅此问题](http://stackoverflow.com/questions/23682232/how-can-i-fix-the-dependencypropertydescriptor-addvaluechanged-memory-leak-on-at) (2认同)

Phi*_*hil 13

这有什么帮助吗?

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)