none
Problem with BindingSource and Dataset.HasChanges RRS feed

  • Question

  • This is a problem which sounds very like others that have been posted, so I apologise if it has been answered before. I have yet to see a definitive solution.

    My form has a parent-child BindingSource on a form, plus a simple combo box which can be used to select which parent row to view/edit.  The parent table is represented by several controls (textbox, checkboxes and a couple of combo boxes), which are bound to a BindingSource, and the Child table is represented by a DataGridView which is bound to a BindingSource which in turn is attached to the relation between the tables. The combobox which is used as a selector for the parent table has its own datasource - a table which I build in the code and which is completely separate from the bindingsources.

    I really want the users to be aware that they have changed a record (and confirm it) BEFORE moving off to another one, so I have this code on the SelectedIndexChanged event on my selector combobox:

    If cmbLimit.SelectedIndex > -1 Then      ' User has selected a different parent record

      If dsLimitsAndSegs.HasChanges Then   ' dsLimitsAndSegs is the dataset with the parent and child tables
        If MsgBox("Save changes?") = vbOK Then
          taSeg.Update(dsLimitsAndSegs.LimitSegment)    ' taSeg is the table adapter doe the child table
          taLimit.Update(dsLimitsAndSegs.LimitLine)         ' taLimit is the table adapter for the parent table
        Else
          dsLimitsAndSegs.RejectChanges()
        End If
      End If

      i = bsParent.Find("ID",cmbLimit.SelectedValue)     ' changes (if any) processed, position binding source to the selected parent row
      if i > -1 then bsParent.Position = i

    End If

    This all works as far as the selection and display of the data is concerned.  The problem is that HasChanges is getting set when no changes have been made.  I do the following sequence of actions:

    1. Open the form.  The first item in the selector combo is selected, and the correct data is displayed.
    2. Select the last item in the selector combo.  The correct data gets displayed.
    3. Select another item in the selector combo. The messagebox to confirm changes pops up!  I have not edited anything.
    4. Any further selection in the selector combo box has the same result.

    I have tried adding some tables etc and using GetChanges to see what has changed, and it seems to be the FIRST parent row.
    This makes no sense to me, and I cannot understand what is going on here. Especially, why does it happen on step 3 but not step 2?

    Weird thing is, if I step through the above code in the debugger, when I step over the bsParent.Find method call, all sorts of stuff pops up in the debug window - including things like calls to OnRowChanged and EndCurrentEdit.

    I am obviously not understanding something, and would appreciate some enlightenment. 

    [Added after further research]
    I've added an event handler for the parent bindingsource, and with that and some further web searching, have discovered that the act of setting the BindingSource.Position fires the CurrentItemChanged event, which is also fired when any of the data in the current item changes.  This then cascades through to the underlying DataSet, and results in HasChanges being set True. So it seems there is no way to distinguish between a simple change of position, and a change in the data - at least not using the BindingSource object. Can this possibly be the case? Seems incredible to me.


    Steve M

    Tuesday, May 17, 2011 7:47 AM

Answers

  • Hi marshallartsoz,

    I think you will need to use the GetChanges method to get the modification record, then compare the current record values to the old values.

    Or you can use a flag to record if you have modified the current record.

    And the options are let you check the value manually, instead of just let the build in method to check the status. Since status and values are different at some time.

     

    Best wishes,


    Mike [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, May 19, 2011 11:51 AM
    Moderator

All replies

  • Hi marshallartsoz,

    I think you will need to use the GetChanges method to get the modification record, then compare the current record values to the old values.

    Or you can use a flag to record if you have modified the current record.

    And the options are let you check the value manually, instead of just let the build in method to check the status. Since status and values are different at some time.

     

    Best wishes,


    Mike [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, May 19, 2011 11:51 AM
    Moderator
  • Well yes, I certainly can do that.  But if that's what has to be done, what on earth is the purpose of the HasChanges property?  Is this conceding that it simply doesn't work?
    Steve M
    Monday, May 23, 2011 8:26 AM
  • I'm afraid, yes it is.

    It just help you to detect the record states, rather than ensure that if the value is really modified.

    So we need to the checking job ourselves.

     

    Best wishes,


    Mike [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, May 23, 2011 9:28 AM
    Moderator