[RESOLVED] Binding Confusion
Hi all,
I have the following code on a form. It uses a Binding Navigator, Binding Source and a Text Box. In the load event, I create a table and set bindings. Everything binds correctly, and the Text Box text changes when I use the navigator.
In the navigator's MoveNext button click handler I fetch the binding source's current row and display the row's value which is bound to the text box. I also output the row's state.
Immediately after the form loads, the text box says "have". If I change it to "must have" and then navigate to the next record, this is what is output to the debug window...
Quote:
Originally Posted by Console Window
must have Unchanged
So the row value is now "Must have", but it was "have" so it has changed yet the row state is unchanged. If I then navigate back to the first record then navigate forward again, the row state finally changes.
So if the row value is different, why is it not reflected in the rowState?
The code; add a binding navigator, binding source and a text box to a form and drop it in...
vb.net Code:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'create the bound table. This will come from mySQL server
Dim dt As New DataTable
dt.Columns.AddRange({New DataColumn("whatToDo")})
dt.Rows.Add("have")
dt.Rows.Add(" a ")
dt.Rows.Add("beer")
dt.Rows.Add(" ;) ")
dt.AcceptChanges()
'set the bindings....
BindingSource1.DataSource = dt
Me.BindingNavigator1.BindingSource = BindingSource1
Me.TextBox1.DataBindings.Add("Text", BindingSource1, "whatToDo")
End Sub
Private Sub BindingNavigatorMoveNextItem_Click(sender As Object, e As EventArgs) Handles BindingNavigatorMoveNextItem.Click
Me.Validate()
Dim row As DataRow = DirectCast(BindingSource1.Current, DataRowView).Row
Dim value As String = row("whatToDo").ToString
Dim rowState = row.RowState
Debug.Print(String.Format("{0} {1}", value, rowState))
End Sub
The whole reason for this is so that I can update the data base if and when a record has changed rather than after the form is closed. If there is a better way, please let me know.
thanks for looking
Kevin
Re: [RESOLVED] Binding Confusion
I've marked this resolved, but I'm still curious if anyone can explain why I get a row from the binding source with changed data yet has a row state that is unchanged.
Re: [RESOLVED] Binding Confusion
Quote:
Originally Posted by
kebo
I've marked this resolved, but I'm still curious if anyone can explain why I get a row from the binding source with changed data yet has a row state that is unchanged.
Timing is everything. :rolleyes:
Nothing has changed in the BindingSource at the point you checked it. The Nav Button Click event is sent before the position is updated.
Edit:
You could force it by calling BindingSource.EndEdit.
Re: [RESOLVED] Binding Confusion
Quote:
Originally Posted by
TnTinMN
Timing is everything. :rolleyes:
Nothing has changed in the BindingSource at the point you checked it.
I get a DataViewRow from the BindingSource, and from it I get the DataRow from the bound table. Using a break point, I can see that data in that row has changed, yet the RowState say it's unchanged. It's either changed or it's not yea?
Re: [RESOLVED] Binding Confusion
I'm guessing that you believe that the call to "Me.Validate" should be pushing the value to the DataSource, but it doesn't.
The BindingSource is bound to the DataTable through the DataTable.DefaultView (a DataView). This is why the BindingSource.Items are type DataRowView. The DataRowView is in an edit mode after you change the bound TextBox.Text. At this point no changes have been pushed back to the DataTable.
You can check the edit state of the DataRowView via its IsEdit property.
VB.Net Code:
Dim drv As DataRowView = DirectCast(BindingSource1.Current, DataRowView)
Dim row As DataRow = drv.Row
If drv.IsEdit Then
drv.EndEdit()
End If
Dim value As String = row("whatToDo").ToString
Dim rowState As DataRowState = row.RowState
Debug.Print(String.Format("{0} {1}", value, rowState))
If the above, EndEdit is called directly on the DataRowView. You could also force it with BindingSource.EndEdit or BindingSource.CurrencyManager.EndCurrentEdit. Pick your poison; or in this case, the cure to your currency dilemma.
You have your code in a method that executes before the BindingSource is kicked in the butt (change position) to do something. After the click handler is finished, the BindingNavigator tells the BindingSource to change the index of its Current item. At that point it ends editing on the previous item (the DataRowView) and the changes are pushed to the DataSource.
If this is still clear as mud, then you'll have to wait for someone else to explain. That's the best I can do.