HasChanges() is always false when rows are modifie

2019-07-26 07:15发布

问题:

So I have a DataSet, that I populate. For test purposes, this contains a single DataTable. This is populated from a query that returns a SQL TABLE which has two columns, ID and Name. This table has one record in it.

I have a single TextBox, that I bind in the following manner:

Dim dv As System.Data.DataView = myDataSet.Tables("MyTable").AsDataView()
dv.RowFilter = "ID=1"

Dim dabi As New Binding("Text", dv, "Name") 
txtInput.DataBindings.Add(dabi)

This all works great in the application! The TextBox populates with the value from the DataSet, and the value stored in the DataSet is updated as I enter stuff into the TextBox.

So, I make a in the TextBox, and then I go to save it.

I call myDataSet.HasChanges(). It returns False, even though I've made a change. Research suggests that this is something to do with the row not believing editing is 'finished' yet, but I'm not certain on this, as I've not been able to find a good source of information on how this is all working.

I have also discovered that HasChanges() will return the correct value (False for no changes, True for changes) if I precede the call to myDataSet.HasChanges() with the following line:

Me.BindingContext(myDataSet.Tables("MyTable")).EndCurrentEdit()

This is a method being called for what appears to be some sort of global binding context. I've not done anything with this, or called any 'Begin Edit' methods, etc (research suggests such things may be private and called implicitly).

My questions then: What's going on here? Why is that line necessary for HasChanges() to work? Am I doing something wrong in my data-binding to necessitate this line? Does that line have any potentially unforeseen side-effects?

EDIT: HasChanges() will correctly return true if new rows are added without the call to EndCurrentEdit(), the issue only arises with modifications to existing rows.

回答1:

Calling EndCurrentEdit cause the changes which you made on an IEditableObject be saved to underlying data source.

Since the DataRowView implements IEditableObject, calling EndCurrentEdit of the currency manager cause EndEdit of DataRowView be called and commits changes to the underlying DataRow and ends the editing session.

Also when you change the position using binding source or change the position by click on another row of grid, if fact you are changing the position of currency manager which case EndCurrentEdit be called.

So to commit changes, you should call EndCurrentEdit directly or indirectly.