none
DataRowState.Modified Question RRS feed

  • Question

  • I have several text boxes and a combobox on a form (all bound to the same table).

    I also have a button to press when the user wants to Post or update.

    I want the Post button to be enabled only when there are changes to the bound controls data. Else I want the Post button to be disabled.

    I'm not sure what table properties to look at or if I even use DataRowState.Modified.

    Can someone please tell me how to do this?

    Thanks,

    Dennis
    Wednesday, December 5, 2007 12:53 PM

Answers

  • There are a couple of different approaches to this problem.

     

    One is to not make it contingent on data binding.  Enable the "Post" button in the property-changed events on your controls.  Advantage:  simple, easy to understand.  Disadvantages:  you have to add an event handler to every control; the "Post" button will remain active even if the user undoes a change.  (Though you can work around this; see below.)

     

    Another is to handle the BindingComplete event on each control's DataBinding.  Advantage:  you don't have to write a different event handler for every type of control.  Disadvantages:  BindingComplete only fires if you have parsing and/or formatting enabled for the binding; if you actually want to examine the value of the property being changed, you have to write some pretty ugly code, e.g.:

     

    Code Block

       if (e.BindingCompleteContext == BindingCompleteContext.DataSourceUpdate)

       {

          Binding b = (Binding)sender;

          Control c = b.BindableComponent;

          string p = b.PropertyName;

          object value = c.GetType().GetProperty(p).GetValue(c, null);

       }

     

     

    If you want the Post button to be enabled if and only if there are pending changes, you have to iterate through the DataRow's DataColumns with logic like this:

     

    Code Block

       bool hasChange = false;

       foreach (DataColumn c in row.Table.Columns)

       {

          if (row[c, DataRowVersion.Current].ToString() != row[c, DataRowVersion.Proposed].ToString())

          {

             hasChange=true;

             break;

          }

       }

     

     

    (Why IEditableObject doesn't include a method that does this is a mystery.)

     

    You can't do anything with DataRowState.Modified (or with the DataTable's RowChanging event), because the row doesn't actually get modified until EndEdit gets called on it, and if I understand your requirements correctly you don't want EndEdit to get called until the user clicks Post.

    Wednesday, December 5, 2007 8:10 PM

All replies

  • What method did you use to "bind" the controls to the table?

    Wednesday, December 5, 2007 2:03 PM
  • I use the (DataBindings) Text in the Properties window.

    I should have mentioned I'm using C# Winforms and SQL
    Wednesday, December 5, 2007 5:10 PM
  • There are a couple of different approaches to this problem.

     

    One is to not make it contingent on data binding.  Enable the "Post" button in the property-changed events on your controls.  Advantage:  simple, easy to understand.  Disadvantages:  you have to add an event handler to every control; the "Post" button will remain active even if the user undoes a change.  (Though you can work around this; see below.)

     

    Another is to handle the BindingComplete event on each control's DataBinding.  Advantage:  you don't have to write a different event handler for every type of control.  Disadvantages:  BindingComplete only fires if you have parsing and/or formatting enabled for the binding; if you actually want to examine the value of the property being changed, you have to write some pretty ugly code, e.g.:

     

    Code Block

       if (e.BindingCompleteContext == BindingCompleteContext.DataSourceUpdate)

       {

          Binding b = (Binding)sender;

          Control c = b.BindableComponent;

          string p = b.PropertyName;

          object value = c.GetType().GetProperty(p).GetValue(c, null);

       }

     

     

    If you want the Post button to be enabled if and only if there are pending changes, you have to iterate through the DataRow's DataColumns with logic like this:

     

    Code Block

       bool hasChange = false;

       foreach (DataColumn c in row.Table.Columns)

       {

          if (row[c, DataRowVersion.Current].ToString() != row[c, DataRowVersion.Proposed].ToString())

          {

             hasChange=true;

             break;

          }

       }

     

     

    (Why IEditableObject doesn't include a method that does this is a mystery.)

     

    You can't do anything with DataRowState.Modified (or with the DataTable's RowChanging event), because the row doesn't actually get modified until EndEdit gets called on it, and if I understand your requirements correctly you don't want EndEdit to get called until the user clicks Post.

    Wednesday, December 5, 2007 8:10 PM