Dataset HasChanges, DataBindings..

JaedenRuiner

Well-known member
Joined
Aug 13, 2007
Messages
340
Programming Experience
10+
Okay,

The Subject may be confusing, but i really couldn't come up a better header for this question.

BindingSource, Binding Navigator, DataSet, Details View

So, the Controls on the Details View all have their Databindings set to the BindingSource. The BindingNavigator has it's DataSource set to the BindingSource, and the BindingSource's Datasource is set to the Dataset. So far pretty standard. (I usually add another button to the BindingNavigator "Cancel" to Cancel any changes currently made to the dataset that have not yet been saved.)

VB.NET:
sub FormTimer_tick() handlies FormTimer.Tick
  Navigator.SaveButton.Enabled =  DataSet.HasChanges 
  Navigator.CancelButton.Enabled =  _
                DataSet.HasChanges(DataRowState.Added Or _
                                             DataRowState.Modified Or _
                                             DataRowState.Deleted)
end sub

Now the Problem:
No matter how much I Edit the Current Record, the Dataset does not recognize any "HasChanges" until I cycle the BindingSource to the Next Record. How can I effect an internal Dataset Update, so that even after changing 1 field (column) of the current record the DataSet knows that changes have been made before I cycle to the next/prev record with the bindingnavigator.

Thanks
 
The Dataset doesn't care how much you edit a datarow. The datarow, datatable and dataset only care when you've finished editing a row. This is when you would usually call DataRow.EndEdit, or it is called implicitly when you cycle to a different row using the BindingNavigator. To affect a change to the dataset/datatable/datarow is a lengthy process and requires caching the original version of the data whilst pushing the new data into the underlying table.

If you really wanted to you could invoke the private method that starts that process using reflection.
 
Hrm.

Okay, so it appears I was using BindingSource.EndEdit() wrongly. I guess then in effect, say i've got 3 textboxes each bound to a column in a DataTable. I could thus do something like this:

VB.NET:
Sub TextBox_Leave() handles Textbox.leave
  if Textbox.Modified then
     bind_src.EndEdit()
  end if
end sub

And by doing that, the DataSet would recognize that a change had been made and the HasChanges() would return true.

The reason is the Cancel effect, not necessarily the save. When I edit a One Textbox, they don't become enabled, because the hasChanges still returns false. From your description, the EndEdit() command would resolve that. Let me know if i'm interpreting this wrong.

Thanks
 
I doubt it, seeing as the bindingsource.EndEdit calls the CurrencyManagers.EndEdit and this is an implementation of IEditableObject. However the Datarow's EndEdit is not an implementation of this interface. So therefore there must be some plumbing somewhere to pass the info along that changes have been made, how and when this happens I don't know without performing some tests. All I do know is that the BindingSource's EndEdit method does not directly call the respective Datarow's EndEdit method.
 
Ahh,

So basically in the Leave() event of the individual controls, I would instead access the BindingSource.Current which is A DataRowView (or DataViewRow, whichever) which has the Row() property which is the current Datarow, and thus call:
VB.NET:
DirectCast(BindingSource.Current, DataViewRow).Row.EndEdit
And that would affect the dataset to know a value has changed.
Right?
 
No? The BS maintains edits in its list separate to the underlying row.. If youre attempting to commit the changes that the BS holds, into the row, then bypassing it and calling endedit on a row that hasnt been changed (at this stage) is a nonop
 
No? The BS maintains edits in its list separate to the underlying row.. If youre attempting to commit the changes that the BS holds, into the row, then bypassing it and calling endedit on a row that hasnt been changed (at this stage) is a nonop

Well i would check to determine if the control's underlying data had changed.
VB.NET:
Dim x as TextBox
if x.Modified then
end if

The whole idea is to trigger via the dataset, the ability to save/cancel changes on a per item alteration as apposed to a per record alteration.

My form utilizes DataSet.HasChanges, but the dataset doesn't "have" any changes until the bindingsource cycles to a different row(record).
 
You do things at strange times! :)

I've never had a problem with:

VB.NET:
  Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing

    Me.Validate()
    Me.DataTable1BindingSource.EndEdit()

    If Me._dataSet1.HasChanges() Then
      If MessageBox.Show("DS has changes. Really exit?", "", MessageBoxButtons.YesNo) = Windows.Forms.DialogResult.No Then e.Cancel = True
    End If

  End Sub
 
:p

Yea, i know. But i'm not trying to save at the end, i'm doing control Enable/Disable on the fly. I have Save and Cancel buttons on my binding navigator, and so I enable them when changes have been made. once you save or cancel the changes they revert back to disabled until changes are made in the future.

I like somewhat intelligent programs that interactively let me know what I've made a change. Like many editor's that keep the opened file name in the title bar and when it's modified they append an asterisk to indicate the file has been altered. I tend to do all that as well in my programs, but right now the enabling effect only takes place when I cycle to the next record and back again.
 
:p

Yea, i know. But i'm not trying to save at the end, i'm doing control Enable/Disable on the fly.

Youre going to struggle.. I'd advocate putting all that creative genius into something the users will a) notice, b) understand and c) care about ;)
 
Back
Top