I promise I've looked at the bazillion posts claiming this same issue, so please forgive me that I am still stumped.
I have a VS2008 smart device project containing a strongly-typed dataset. The user is allowed to input values and save them, each time creating a new record in the dataset. Should the user wish to edit values, a modal child form is displayed with several combo boxes containing the possible values for acceptable input to edit the row. Each combo box is bound in the constructor for the child form in the fashion below:
With cmbSize
.DataSource = frmMain.dstConfig.Sizes
.DisplayMember = "Display"
.ValueMember = "Value"
.DataBindings.Add("SelectedValue", trowNewRow, "SIZE", True, DataSourceUpdateMode.OnPropertyChanged)
End With
dstConfig is a dataset of tables containing the constraints. Binding to the source's display and value members works fine.
trowNewRow is a reference to the row in the dataset conveyed from the main form when the user initiates an edit procedure, to the child form by passing the row as a parameter "ByRef". The strong-typing is preserved. It occurred to me there may be some sort of a disconnection that I am not aware of when this occurs. I pass the reference by performing a "Select" procedure on the dataset and filtering by a unique ID field corresponding to the row that is to be edited. The result is a single-item array of strongly-typed rows of the same schema as the dataset's from which I pass the first (and only) item as my object.
After the user submits the changes by clicking an OK button, a procedure is triggered to evaluate whether or not a change was actually performed. The best way I thought to do this was by checking the RowState of trowNewRow. The RowState, however, remains "Added" regardless of the changes. Manually checking the values of the row indicates the changes have indeed been recorded. I've verified the AcceptChanges procedure of trowNewRow is not explicitly being called by any of my code.
I have tried the following: 1.) Calling the EndEdit procedure of trowNewRow 2.) Manually performing a WriteValue on the combo boxes 3.) Calling the EndCurrentEdit procedure on the combo boxes' BindingManagerBase objects 4.)Every combination of the above
Thank you in advance for any ideas or solutions.
A DataRow
contains two sets of data - original and current - and the RowState
reflects the relationship between them. If there is no original data but there is current data then the RowState
is Added
. As @Plutonix says, no amount of editing the current data is going to add original data so the RowState
remains Added
even if you make further changes. If there is no current data but there is original data then the RowState
is Deleted
. If the current data matches the original data then the RowState
is Unchanged
, otherwise it's Modified
.
When you call Update
on a data adapter or table adapter, the InsertCommand
is executed for each Added
row, the UpdateCommand
is executed for each Modified
row and the DeleteCommand
is executed for each Deleted
row. After a successful save, the adapter implicitly calls AcceptChanges
. That will remove all Deleted
rows from the DataTable
and copy the current values in Added
and Modified
rows over the original values, changing the RowState
to Unchanged
.
So, the RowState
is for tracking changes since the last save to the database. You can't use it to determine whether the user has made any changes in the UI unless you are saving those changes to the database after every edit. If you want finer-grained change-tracking then you have to implement it yourself. Personally, I don't bind in those cases but wait until the user clicks OK to push the data into the DataRow
. That also allows you to cancel the latest edit without losing prior edits.