WPF: Detect Datagrid changes

wpf datagrid cell value change event mvvm
wpf datagrid update cell value
c# wpf datagrid changed
datagrid cell text changed
datagrid edit event
wpf datagrid row change event
wpf datagrid events
wpf datagrid selectionchanged

I have a datagrid

<DataGrid ItemsSource="{Binding MyList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
  <DataGrid.Columns>
    <DataGridTextColumn Header="Name"
                                Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
  </DataGrid.Columns>
</DataGrid>

It's source

    /*** Added constructor ***/
    public SetupVM()
    {
        ConnectionString = Path.Combine(DATABASE_PATH, DATABASE_NAME);
        MyList = new List<MyObjectINotifyImplemented>();

        /* MyList= new ObservableCollection<MyObjectINotifyImplemented>(); */

        if (!File.Exists(ConnectionString))
        {
            FirstRun();
        }
    }

    public void FirstRun()
    {
        BoilerPlate boilerPlate = new BoilerPlate();
        Directory.CreateDirectory(DATABASE_PATH + "\\databaseFile");

        using (SQLiteConnection conn = new SQLiteConnection(ConnectionString))
        {
            conn.CreateTable<MyObjectINotifyImplemented>();

            foreach (seed in MyObjectINotifyImplemented.seeds)
            {
                var t = conn.Insert(seed);
            }
        }
    }

    private List<MyObjectINotifyImplemented> _mylist;

    public List<MyObjectINotifyImplemented> MyList
    {
        get { return _mylist; }
        set
        {
            _mylist= value;
            /****  Called on initialization in ctor and never again ****/
            MyMethodThatShouldBeCalled();
        }
    }

Sample of the model:

class MyObjectINotifyImplemented : INotifyPropertyChanged
{
  [PrimaryKey, AutoIncrement]
  public int Id { get; set; }
  private string _name;

  public string Name
  {
    get { return _name; }
    set
    {
      _name = value;
      OnPropertyChanged("Name");
    }
  }

  /** Generated by VS **/
  public event PropertyChangedEventHandler PropertyChanged;

  [NotifyPropertyChangedInvocator]
  protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
  {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }
}

I see this question asked over and over again, but I'm implementing everything that I can find?

Most questions are resolved by binding mode or adding UpdateSourceTrigger=PropertyChanged.

What could be missing? Ignore typos, I just cut out the relevant bits by hand.

Most questions are resolved by binding mode or adding UpdateSourceTrigger=PropertyChanged.

It only makes sense to set the UpdateSourceTrigger and Mode properties when the control actually may actually set the source property. A DataGrid does not set the source of the ItemsSource property so setting these properties are pointless in this context.

The DataGrid will never call the setter of your MyList source property. Only the getter will be called. This is the expected behaviour. You should define the binding like this:

<DataGrid ItemsSource="{Binding MyList}">

If you for example bind the Text property of a TextBox, it does makes sense to specify an UpdateSourceTrigger and a Mode to control when and if the TextBox sets the source property. But it doesn't when binding the ItemsSource property of an ItemsControl.

It's unclear why you expect or want the setter of the source collection property to get called by the framework here because it's not supposed to. And it won't.

If you want to detect items being added or removed from the DataGrid, you should replace the List<MyObjectINotifyImplemented> with an ObservableCollection<MyObjectINotifyImplemented> and handle the CollectionChanged event of the source collection. The collection itself won't be replaced.

[Solved] WPF DataGrid Row Changed, I think you need to handle SelectedCellsChanged for more info ;) in WPF DataGrid how to force lost focus (and thereby commit) of a datagrid row when rightclicking outside it 29 How to raise an event when DataGrid.ItemsSource is changed

Change the definition of MyList from List<MyObjectINotifyImplemented> to ObservableCollection<MyObjectINotifyImplemented> which is what you are newing up in the constructor.

https://social.msdn.microsoft.com/Forums/vstudio/e, Occurs when the collection changes. sender, SelectedCellsChangedEventArgs e) { //Get the newly selected cells IList<​DataGridCellInfo> selectedcells = e. The WPF DataGrid operates in a row-oriented manner making this a relatively straightforward scenario to implement. However, what if you want to commit changes on a cell-by-cell basis? Firstly, lets have a look at the problem in a bit more detail. The following code displays a DataGrid, together with a 'details' view.

Sorry to sound negative on your issue, but it should only be called once. That is the only place where you are actually loading the list. Unless there is something else on the form that will force some refresh and requery your data such as from your connection string / database, it wont. All you have is

  1. Prepare an empty list (that should be ObservableCollection)
  2. Define your data grid (but still nothing indicating the forms DataContext is actually set)
  3. Your no file based on your connectionString setting, you call FirstRun, but don't show what FirstRun does.
  4. If the file expected DOES exist, it does not show you querying anything TO populate it.

You have provided a variety of partial implementations, but obviously not enough to get the rest of the functionality across.

DataGrid.SelectedCellsChanged Event (System.Windows.Controls , WPF DataGrid - detecting the column, cell and row that has been wpfdatagridmouseclicks, changing the file extension from .doc to .zip. I see CellValueChanged, but this fires even when cell values are changed programatically, and doesn't have any sort of flag in the event args denoting if it was a user-initiated change. There's also the CellEndEdit event, but it doesn't tell you directly whether or not the value was actually changed.

WPF DataGrid, These examples all worked on the assumption that you want to keep your database synchronised with the DataGrid, with changes being  Each time the contents of this TextBox are changed, the TextChanged event fires and textChangedEventHandler is called. </TextBox> Example. In the code-behind class for the XAML that contains the TextBox control that you want to monitor for changes, insert a method to call whenever the TextChanged event fires.

WPF DataGrid - Committing changes cell-by-cell, SfDataGrid supports to commit and roll back the changes in row level when underlying data object implements IEditableObject interface. The editing changes in a  I am trying to detect when changes occur to the underlying database via ANY source. I essentially want this up on my screen and to go update a field via SSMS and to see the update take place in my currently running application as well!

Editing in WPF DataGrid control, Hi; i am trying to catch Cell value changed event on a WPF DataGrid, the needed behavior is that we need an event to fire every time user clicks on a CheckBox  I have a program that displays DataGrid views successfully; however, when attempting to get it to save changes to the database when data is changed, I am running into a bit of an obstacle. Here is the code I have to fill the database. The last three lines where the SqlCommandBuilder begins is where I am attempting to get it to update.

Comments
  • What exactly is the problem, it sounds like you have a data change you are not seeing? Or the binding is not showing at all?
  • MyMethodThatShouldBeCalled(); is never called.
  • Where do you attempt to assign the list?
  • I'm sorry I don't understand?
  • You have to make an assignment like MyList = new <MyObjectINotifyImplemented>() { new MyObjectINotifyImplemented() } somewhere. Until that assignments happens, the call to MyMethodThatShouldBeCalled won't be called. There has to be an assignment somewhere otherwise the reference to MyList will remain null.
  • So if I understand you correctly, DataGrid's are not supporting two-way binding? Because I find hundreds of questions on Stack Overflow asking to set this up, most of which have a successful outcome. I also don't see anything like this on Microsoft docs, where would one look? The List<> or Observable collection is sourced from a SQLite DB. What I would like to do is write to the DB when one of the rows is updated, which is what MyMethodThatShouldBeCalled() is supposed to handle. I will look into the CollectionChanged event, cheers.
  • @ArchieMoses: When a property of an object that is represented by a row is updated, the setter of this property is called. That would be the Name property in your example. But the source collection property is not affected.
  • Argh, typo. I tried both, this was a C&P mistake from the latest attempt.
  • No need for sorry, thanks for reading. I've added the code, it is just seeding with default data. Binding back to front works just fine, it's the other way that is not working.