Search code examples
c#wpfmvvmdatagrid

How can I track changes of a DataGrid WPF MVVM


I have a WPF/MVVM application where I want to track when the user changes some data in the datagrid. The DataGrid has a ICollectionView as source which is filled by a DataTable:

private ICollectionView _planningCollectionView;

public ICollectionView PlanningCollectionView
{
    get => _planningCollectionView;
    set
    {
        if (_planningCollectionView == value) return;
        _planningCollectionView = value;
        OnPropertyChanged();
    }
}

...
//_planningView is my DataTable
public MainViewModel()
{
    ...
    PlanningCollectionView = CollectionViewSource.GetDefaultView(_planningView);
    ...
}

The goal is, to make a little status bar where the user is able to see if there are unsaved changes.

NoUnsavedChanges UnsavedChanges

On top of that, i want to verify, if the user didnt put the original data back. For example if a cell had the value "50" on the initial DataGrid load and the user changes it to "100" then the status should show "Unsaved changes". When the user changes it back to "50" the status should go back to "No unsaved changes."

My Approach:

I tried using the "CellEditEnding" and the "RowEditEnding" events to track when the user finished his input. This is followed by a InvokeCommandAction which calls a command defined in my MainViewModel. The Command just points to a method which only sets a DataTable with all the changes of my first DataTable

public void SetEdited()
{
    DataTable planningViewChanges = _planningView.GetChanges();
}

The Outcome:

When I put a breakingpoint in my method I see that it gets called after i clicked besides the edited cell. But I think its suspicious that the cell didnt end the ending completely when my breakpoint stops.

Outcome

And when I look in my method and inspect my DataTable object "planningViewChanges" it is null. When I continue the application and the editing visually ends in the cell and I try to change another cell or I call my Command through a button and I inspect the DataTable "planningViewChanges" again it has one row. So obviously, the commit of the data in the DataGrid to the source DataTable is working, but not right after the "CellEditEnding" or "RowEditEnding" event...

My Second Approach

I googled and browsed many other questions that could be similar to this issue. One approach was using the "LostFocus" even on the DataGrid, but this didnt fired after the commit too. When i tried to change the UpdateSourceTrigger option to "LostFocus"or "PropertyChanged" the commit didnt started before the event either...

In Addition

Another approach I've read was using a list of a custom class. But this isnt suitable for my problem because the DataGrid columns can vary with their number dynamically.

Addition

My Question

Does anybody know how to get an event that is fired after the editing of a cell and after the commit? Or is there a solution that is more fitted for the MVVM Pattern? Many answers on similar questions didnt really had much in common and everybody had his/her own opinion on what is MVVM like and what is not..


Solution

  • I found another event that fires right after the commit. The event "CurrentCellChanged" works, but must be treated with caution. It fires everytime you change the current selected cell (as you can see on the name) so even when you start editing the cell. I made some changes in my called method so my whole logic doesnt fire everytime but only if i want to track changed cells(rows).