Interminable Interminable - 4 months ago 13
Vb.net Question

HasChanges() is always false when rows are modified unless I call the form's BindingContext EndCurrentEdit() method

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.

Answer

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.