40

I am new in WPF, and I am working with DataGrids and I need to know when the property ItemsSource is changed.

For example, I would need that when this instruction is executed an event has to raise:

dataGrid.ItemsSource = table.DefaultView;

Or when a row is added.

I have tried to use this code:

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

But this code works only when the user adds a new row to the collection. Therefore I need a event that be raised when the entire ItemsSource property has any change, either because the entire collection is replaced or because a single row is added.

I hope you can help me. Thank you in advance

Dante
  • 3,208
  • 9
  • 38
  • 56

3 Answers3

77

ItemsSource is a dependency property, so it's easy enough to be notified when the property is changed to something else. You would want to use this in addition to code that you have, not instead of:

In Window.Loaded (or similar) you can subscribe like so:

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

And have a change handler:

private void ThisIsCalledWhenPropertyIsChanged(object sender, EventArgs e)
{
}

Whenever the ItemsSource Property is set, the ThisIsCalledWhenPropertyIsChanged method is called.

You can use this for any dependency property you want to be notified about changes.

vcsjones
  • 138,677
  • 31
  • 291
  • 286
  • 3
    Very nice! Exactly what i was looking for. – austin wernli Jun 01 '15 at 20:17
  • Allows to create nice control behaviour, if inheriting from standard controls! – BendEg Sep 14 '15 at 11:29
  • 6
    One thing to keep in mind is that this pattern creates a bad memory leak if not explicitly removed. The source object (`myGrid` in this answer) can never be garbage collected, since the static `DependencyPropertyDescriptor` holds a strong reference to it for the lifetime of the application. [See this question for details](http://stackoverflow.com/questions/23682232/how-can-i-fix-the-dependencypropertydescriptor-addvaluechanged-memory-leak-on-at) – Andrew Hanlon Sep 20 '16 at 13:31
21

Is this any help?

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();
        }
    }
}
Phil
  • 42,255
  • 9
  • 100
  • 100
-1

If you wnat to detect new row added can try DataGrid's InitializingNewItem or AddingNewItem Event.

InitializingNewItem usage :

Datagrid auto add item with data of parent

Community
  • 1
  • 1
yu yang Jian
  • 6,680
  • 7
  • 55
  • 80