Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / WinForm Data Binding / July 2004

Tip: Looking for answers? Try searching our database.

Error recovery durring AddNew

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Gary Shell - 14 Jul 2004 16:23 GMT
I have a simple data form that can edit and add records to a table.  In my
"OK Button" code I EndCurrentEdit and then perform a UPDATE method on the
data adapter.  It works just fine adding and editing data.

One field on the table is a foreign key and I have referential integrity
enforced on the server.  When adding a new record I catch the exception
raised by the Update method if the user supplies invalid data and display an
error message.  I then allow the user to fix the problem and hit the OK
button again.  The problem is when I get to the Update method again the
underlying row in the dataset seems to be no longer bound to my controls.
That is, if I go in and look at the contents of the item collection for the
row being added the field that triggered the exception is still null.  It
does not have the value in the control that the user just corrected.

Is there something I need to tell the dataset or more likely the data
adapter that we are "retrying" the update?

Sign me somewhat confused, but impressed, by this .Net databinding.

Gary
a - 14 Jul 2004 18:11 GMT
Post some code for this.  I am wondering a few things:  are you binding to
datasets?  Do you have the relation in the dataset?  That would let you
catch the violation prior to going to the server
in the call to EndCurrentEdit.

Kevin

> I have a simple data form that can edit and add records to a table.  In my
> "OK Button" code I EndCurrentEdit and then perform a UPDATE method on the
[quoted text clipped - 16 lines]
>
> Gary
Gary Shell - 14 Jul 2004 18:22 GMT
I am bound to a dataset.  There is no relation in the dataset.  The
EndCurrentEdit does not make a trip to the server.  (only an UPDATE method
would do that.)  The exception is actually occurring in the EndCurrentEdit
because there is a No Nulls constraint on the column in question.  I've dug
into this a bit further and when the EndCurrentEdit is executed if the
exception occurs ALL of the data in the items collection for the new row is
set to "".    I don't understand why that should be.

Gary

> Post some code for this.  I am wondering a few things:  are you binding to
> datasets?  Do you have the relation in the dataset?  That would let you
[quoted text clipped - 25 lines]
> >
> > Gary
a - 14 Jul 2004 19:32 GMT
Sorry, I thought you were gettin ghte error on the Update call, not the
EndCurrentEdit..  Didn't know you had the constraint in the dataset.

Why not perform the check in the GUI before the call to EndCurrentEdit?

Kevin

> I am bound to a dataset.  There is no relation in the dataset.  The
> EndCurrentEdit does not make a trip to the server.  (only an UPDATE method
[quoted text clipped - 40 lines]
> > >
> > > Gary
Gary Shell - 14 Jul 2004 20:21 GMT
Yeah, I was a bit obtuse in my initial description.

You are correct I could add code to check for the null first.  But I am
trying to figure out why the EndCurrentEdit clears the dataset's item
collection when an exception occurs.  I want to know what to expect when
some OTHER exception occurs, not just the one for this constraint.

Gary

> Sorry, I thought you were gettin ghte error on the Update call, not the
> EndCurrentEdit..  Didn't know you had the constraint in the dataset.
[quoted text clipped - 56 lines]
> > > >
> > > > Gary
a - 15 Jul 2004 17:00 GMT
> You are correct I could add code to check for the null first.  But I am
> trying to figure out why the EndCurrentEdit clears the dataset's item
[quoted text clipped - 70 lines]
> > > > >
> > > > > Gary
Gary Shell - 15 Jul 2004 22:03 GMT
First let me say I'm glad we are still talking.  I was afraid I might have pissed you off in our exchange about crossposting.

The GUI is pretty simple.  I will distill it further though to make this brief.  I have a text field called MetricName bound to txtMetricName.  I have a MetricClass field (with a no null constraint) bound to a combo box's SelectedValue property.  The list portion of the combo is bound to a table called MetricClasses.  There are a few other fields including a couple of booleans.  

If I add a new record all fields on the form are blanked, as expected.  I then type a MetricName and NOTHING else, then hit my update code, the EndCurrentEdit method throws an exception about the null state of MetricClass, again as expected.

I have a watch variable set to me.dsMetric.ItemArray and just before the EndCurrentEdit I can see the text I typed into the txtMetricName textbox in the correct ItemArray element.  (I can also see the contents of the other textboxes and checkboxes as well.)  But as soon as the EndCurrentEdit throws the exception, the entire ItemArray is reset.  By that I mean, all Items are cleared to a valid state for a new row, i.e.  all non-nullable fields are set to "", all nullable fields are set to null and all fields with declared default values have their correct defaults (only my booleans have default declared some true some false).  These same values from this ItemArray are also populated back to the bound controls, wiping out whatever I'd typed into the various text boxes.  

What happens to your ItemArray after such an exception.  What happens to your form controls?  I'm desperately trying to figure out a way to preserve their state so I can retry the EndCurrentEdit.   That brings up a point, after your exception is thrown, and you click save a second time exactly what does your code do?  Does it do another EndCurrrentEdit and if that works you use an UPDATE method on the dataadapter?

Hope this is a bit clearer.

And thanks for sticking with me on this!!!!!!

Try    Me.cm.EndCurrentEdit()    Me.lblInfo.Text = "Record Successfully Saved"    booDirty = FalseCatch ex As Exception    Me.lblInfo.Text = ex.MessageEnd Try This works for me. I have some columns that do not allow Nulls.  When I click save, if there is an error (a no-null is still DBNull.Value) it shows it to the user.  They can then fix it and click save and all is well.Explain your GUI to me a little better. Kevin  "Gary Shell" <gshell@fuse.net> wrote in message news:uN6ODfdaEHA.596@TK2MSFTNGP11.phx.gbl...> Yeah, I was a bit obtuse in my initial description.
 >
 > You are correct I could add code to check for the null first.  But I am
 > trying to figure out why the EndCurrentEdit clears the dataset's item
 > collection when an exception occurs.  I want to know what to expect when
 > some OTHER exception occurs, not just the one for this constraint.
 >
 > Gary
 >
 >
 > "a" <a@a.com> wrote in message
 > news:%231%23ozDdaEHA.556@tk2msftngp13.phx.gbl...
 > > Sorry, I thought you were gettin ghte error on the Update call, not the
 > > EndCurrentEdit..  Didn't know you had the constraint in the dataset.
 > >
 > > Why not perform the check in the GUI before the call to EndCurrentEdit?
 > >
 > > Kevin
 > >
 > > "Gary Shell" <gshell@fuse.net> wrote in message
 > > news:%231gacccaEHA.1248@TK2MSFTNGP11.phx.gbl...
 > > > I am bound to a dataset.  There is no relation in the dataset.  The
 > > > EndCurrentEdit does not make a trip to the server.  (only an UPDATE
 > method
 > > > would do that.)  The exception is actually occurring in the
 > EndCurrentEdit
 > > > because there is a No Nulls constraint on the column in question.  I've
 > > dug
 > > > into this a bit further and when the EndCurrentEdit is executed if the
 > > > exception occurs ALL of the data in the items collection for the new row
 > > is
 > > > set to "".    I don't understand why that should be.
 > > >
 > > > Gary
 > > >
 > > > "a" <a@a.com> wrote in message
 > > > news:%23FF0gWcaEHA.3480@TK2MSFTNGP11.phx.gbl...
 > > > > Post some code for this.  I am wondering a few things:  are you
 > binding
 > > to
 > > > > datasets?  Do you have the relation in the dataset?  That would let
 > you
 > > > > catch the violation prior to going to the server
 > > > > in the call to EndCurrentEdit.
 > > > >
 > > > > Kevin
 > > > >
 > > > >
 > > > >
 > > > >
 > > > > "Gary Shell" <gshell@fuse.net> wrote in message
 > > > > news:OlCz$ZbaEHA.2520@TK2MSFTNGP12.phx.gbl...
 > > > > > I have a simple data form that can edit and add records to a table.
 > > In
 > > > my
 > > > > > "OK Button" code I EndCurrentEdit and then perform a UPDATE method
 > on
 > > > the
 > > > > > data adapter.  It works just fine adding and editing data.
 > > > > >
 > > > > > One field on the table is a foreign key and I have referential
 > > integrity
 > > > > > enforced on the server.  When adding a new record I catch the
 > > exception
 > > > > > raised by the Update method if the user supplies invalid data and
 > > > display
 > > > > an
 > > > > > error message.  I then allow the user to fix the problem and hit the
 > > OK
 > > > > > button again.  The problem is when I get to the Update method again
 > > the
 > > > > > underlying row in the dataset seems to be no longer bound to my
 > > > controls.
 > > > > > That is, if I go in and look at the contents of the item collection
 > > for
 > > > > the
 > > > > > row being added the field that triggered the exception is still
 > null.
 > > > It
 > > > > > does not have the value in the control that the user just corrected.
 > > > > >
 > > > > > Is there something I need to tell the dataset or more likely the
 > data
 > > > > > adapter that we are "retrying" the update?
 > > > > >
 > > > > > Sign me somewhat confused, but impressed, by this .Net databinding.
 > > > > >
 > > > > > Gary
Gary Shell - 15 Jul 2004 23:06 GMT
Another quick thought.  I wonder if this has anything to do with the fact that my AddNew procedure uses the technique described below.  I don' t add the new row to the bindingcontext.  I add it directly to the dataset.  This does seem to work OK when no exceptions are thrown.   But I wonder if when the exception IS thrown if the fact that the BindingContext didn't know I anything about the added row is causing the weirdness I see.

Here's the pertinent text from a file found on Microsoft's site:

However, these auto-generated programs have a major limitation. If the data being accessed has any fields that cannot be null (because the database schema does not allow nulls), then the program generated by the wizard will be unable to add records. When the Add button is pressed, an error message will indicate the first field in the record that is not allowed to be null. (If you don't have the latest service packs applied, you may not see the error message but the program will still refuse to add a record.)

The problem is that the Data Form Wizard uses the BindingContext object to add a row to the bound DataTable. Here is the code that fails in the btnAdd_Click event routine:

Me.BindingContext(objProducts, "Products").AddNew()
The solution is to bypass the BindingContext object for new rows. Below is the typical code to add a new row. This code should replace the single line of code above:

Dim dr As DataRow
dr = objProducts.Tables("Products").NewRow
dr.Item("ProductName") = ""
dr.Item("Discontinued") = False
' Set any other fields that cannot null to default values.
objProducts.Tables("Products").Rows.Add(dr)
 First let me say I'm glad we are still talking.  I was afraid I might have pissed you off in our exchange about crossposting.

 The GUI is pretty simple.  I will distill it further though to make this brief.  I have a text field called MetricName bound to txtMetricName.  I have a MetricClass field (with a no null constraint) bound to a combo box's SelectedValue property.  The list portion of the combo is bound to a table called MetricClasses.  There are a few other fields including a couple of booleans.  

 If I add a new record all fields on the form are blanked, as expected.  I then type a MetricName and NOTHING else, then hit my update code, the EndCurrentEdit method throws an exception about the null state of MetricClass, again as expected.

 I have a watch variable set to me.dsMetric.ItemArray and just before the EndCurrentEdit I can see the text I typed into the txtMetricName textbox in the correct ItemArray element.  (I can also see the contents of the other textboxes and checkboxes as well.)  But as soon as the EndCurrentEdit throws the exception, the entire ItemArray is reset.  By that I mean, all Items are cleared to a valid state for a new row, i.e.  all non-nullable fields are set to "", all nullable fields are set to null and all fields with declared default values have their correct defaults (only my booleans have default declared some true some false).  These same values from this ItemArray are also populated back to the bound controls, wiping out whatever I'd typed into the various text boxes.  

 What happens to your ItemArray after such an exception.  What happens to your form controls?  I'm desperately trying to figure out a way to preserve their state so I can retry the EndCurrentEdit.   That brings up a point, after your exception is thrown, and you click save a second time exactly what does your code do?  Does it do another EndCurrrentEdit and if that works you use an UPDATE method on the dataadapter?

 Hope this is a bit clearer.

 And thanks for sticking with me on this!!!!!!

 Gary
   "a" <a@a.com> wrote in message news:%23IWxKToaEHA.3508@TK2MSFTNGP09.phx.gbl...
Try    Me.cm.EndCurrentEdit()    Me.lblInfo.Text = "Record Successfully Saved"    booDirty = FalseCatch ex As Exception    Me.lblInfo.Text = ex.MessageEnd Try This works for me. I have some columns that do not allow Nulls.  When I click save, if there is an error (a no-null is still DBNull.Value) it shows it to the user.  They can then fix it and click save and all is well.Explain your GUI to me a little better. Kevin  "Gary Shell" <gshell@fuse.net> wrote in message news:uN6ODfdaEHA.596@TK2MSFTNGP11.phx.gbl...> Yeah, I was a bit obtuse in my initial description.
   >
   > You are correct I could add code to check for the null first.  But I am
   > trying to figure out why the EndCurrentEdit clears the dataset's item
   > collection when an exception occurs.  I want to know what to expect when
   > some OTHER exception occurs, not just the one for this constraint.
   >
   > Gary
   >
   >
   > "a" <a@a.com> wrote in message
   > news:%231%23ozDdaEHA.556@tk2msftngp13.phx.gbl...
   > > Sorry, I thought you were gettin ghte error on the Update call, not the
   > > EndCurrentEdit..  Didn't know you had the constraint in the dataset.
   > >
   > > Why not perform the check in the GUI before the call to EndCurrentEdit?
   > >
   > > Kevin
   > >
   > > "Gary Shell" <gshell@fuse.net> wrote in message
   > > news:%231gacccaEHA.1248@TK2MSFTNGP11.phx.gbl...
   > > > I am bound to a dataset.  There is no relation in the dataset.  The
   > > > EndCurrentEdit does not make a trip to the server.  (only an UPDATE
   > method
   > > > would do that.)  The exception is actually occurring in the
   > EndCurrentEdit
   > > > because there is a No Nulls constraint on the column in question.  I've
   > > dug
   > > > into this a bit further and when the EndCurrentEdit is executed if the
   > > > exception occurs ALL of the data in the items collection for the new row
   > > is
   > > > set to "".    I don't understand why that should be.
   > > >
   > > > Gary
   > > >
   > > > "a" <a@a.com> wrote in message
   > > > news:%23FF0gWcaEHA.3480@TK2MSFTNGP11.phx.gbl...
   > > > > Post some code for this.  I am wondering a few things:  are you
   > binding
   > > to
   > > > > datasets?  Do you have the relation in the dataset?  That would let
   > you
   > > > > catch the violation prior to going to the server
   > > > > in the call to EndCurrentEdit.
   > > > >
   > > > > Kevin
   > > > >
   > > > >
   > > > >
   > > > >
   > > > > "Gary Shell" <gshell@fuse.net> wrote in message
   > > > > news:OlCz$ZbaEHA.2520@TK2MSFTNGP12.phx.gbl...
   > > > > > I have a simple data form that can edit and add records to a table.
   > > In
   > > > my
   > > > > > "OK Button" code I EndCurrentEdit and then perform a UPDATE method
   > on
   > > > the
   > > > > > data adapter.  It works just fine adding and editing data.
   > > > > >
   > > > > > One field on the table is a foreign key and I have referential
   > > integrity
   > > > > > enforced on the server.  When adding a new record I catch the
   > > exception
   > > > > > raised by the Update method if the user supplies invalid data and
   > > > display
   > > > > an
   > > > > > error message.  I then allow the user to fix the problem and hit the
   > > OK
   > > > > > button again.  The problem is when I get to the Update method again
   > > the
   > > > > > underlying row in the dataset seems to be no longer bound to my
   > > > controls.
   > > > > > That is, if I go in and look at the contents of the item collection
   > > for
   > > > > the
   > > > > > row being added the field that triggered the exception is still
   > null.
   > > > It
   > > > > > does not have the value in the control that the user just corrected.
   > > > > >
   > > > > > Is there something I need to tell the dataset or more likely the
   > data
   > > > > > adapter that we are "retrying" the update?
   > > > > >
   > > > > > Sign me somewhat confused, but impressed, by this .Net databinding.
   > > > > >
   > > > > > Gary
a - 15 Jul 2004 23:44 GMT
Yeah . . . .  I neglected to see you are not using a CurrencyManager.

That will solve all your problems (and may create new ones.)  I have a hard time getting the MS Solution to work in my live Apps.  In their solution, you would need to set your Non-Nullable field to something (0 or ""), otherwise you get the error on .Rows.Add(dr)

The following does not work for all controls (checkbox deos not work), but it does work for TextBox and ComboBox:

Public WithEvents cm As CurrencyManager

Private Sub frmTaskEntry_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
     
Me.cboType.DataBindings.Add(New System.Windows.Forms.Binding("SelectedValue", TaskData.Data.dsTaskData1, "tblTask.TypeRef"))
Me.cboType.DataSource = TaskData.Data.dsTaskData1
Me.cboType.DisplayMember = "tblType.Name"
Me.cboType.ValueMember = "tblType.ID"

cm = Me.BindingContext(TaskData.Data.dsTaskData1, "tblTask")

cm.AddNew()

' USED TO PROGRAMMATICALLY SET A VALUE IN THE NEW ROW
       drv = CType(cm.Current, DataRowView)
       'Set ProjectRef
       drv.Item("ProjectRef") = intProjectRef
cm.Refresh()

End Sub

Private Sub butSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butSave.Click
       Try
           Me.cm.EndCurrentEdit()
           Me.lblInfo.Text = "Record Successfully Saved"
           booDirty = False
       Catch ex As Exception
           Me.lblInfo.Text = ex.Message
       End Try
End Sub

'--------

The
        drv = CType(cm.Current, DataRowView)
       'Set ProjectRef
       drv.Item("ProjectRef") = intProjectRef

part needs to be done on columns bound to CheckBoxes, NumericUpDowns, DateTimePickers . . .

Check out the CurrencyManager, which is the result of me.BindingContext when the binding is complex.

Kevin

 Another quick thought.  I wonder if this has anything to do with the fact that my AddNew procedure uses the technique described below.  I don' t add the new row to the bindingcontext.  I add it directly to the dataset.  This does seem to work OK when no exceptions are thrown.   But I wonder if when the exception IS thrown if the fact that the BindingContext didn't know I anything about the added row is causing the weirdness I see.

 Here's the pertinent text from a file found on Microsoft's site:

 However, these auto-generated programs have a major limitation. If the data being accessed has any fields that cannot be null (because the database schema does not allow nulls), then the program generated by the wizard will be unable to add records. When the Add button is pressed, an error message will indicate the first field in the record that is not allowed to be null. (If you don't have the latest service packs applied, you may not see the error message but the program will still refuse to add a record.)

 The problem is that the Data Form Wizard uses the BindingContext object to add a row to the bound DataTable. Here is the code that fails in the btnAdd_Click event routine:

Me.BindingContext(objProducts, "Products").AddNew()
The solution is to bypass the BindingContext object for new rows. Below is the typical code to add a new row. This code should replace the single line of code above:

Dim dr As DataRow
dr = objProducts.Tables("Products").NewRow
dr.Item("ProductName") = ""
dr.Item("Discontinued") = False
' Set any other fields that cannot null to default values.
objProducts.Tables("Products").Rows.Add(dr)
"Gary Shell" <gshell@fuse.net> wrote in message news:ubx868qaEHA.1764@TK2MSFTNGP10.phx.gbl...
   First let me say I'm glad we are still talking.  I was afraid I might have pissed you off in our exchange about crossposting.

   The GUI is pretty simple.  I will distill it further though to make this brief.  I have a text field called MetricName bound to txtMetricName.  I have a MetricClass field (with a no null constraint) bound to a combo box's SelectedValue property.  The list portion of the combo is bound to a table called MetricClasses.  There are a few other fields including a couple of booleans.  

   If I add a new record all fields on the form are blanked, as expected.  I then type a MetricName and NOTHING else, then hit my update code, the EndCurrentEdit method throws an exception about the null state of MetricClass, again as expected.

   I have a watch variable set to me.dsMetric.ItemArray and just before the EndCurrentEdit I can see the text I typed into the txtMetricName textbox in the correct ItemArray element.  (I can also see the contents of the other textboxes and checkboxes as well.)  But as soon as the EndCurrentEdit throws the exception, the entire ItemArray is reset.  By that I mean, all Items are cleared to a valid state for a new row, i.e.  all non-nullable fields are set to "", all nullable fields are set to null and all fields with declared default values have their correct defaults (only my booleans have default declared some true some false).  These same values from this ItemArray are also populated back to the bound controls, wiping out whatever I'd typed into the various text boxes.  

   What happens to your ItemArray after such an exception.  What happens to your form controls?  I'm desperately trying to figure out a way to preserve their state so I can retry the EndCurrentEdit.   That brings up a point, after your exception is thrown, and you click save a second time exactly what does your code do?  Does it do another EndCurrrentEdit and if that works you use an UPDATE method on the dataadapter?

   Hope this is a bit clearer.

   And thanks for sticking with me on this!!!!!!

   Gary
     "a" <a@a.com> wrote in message news:%23IWxKToaEHA.3508@TK2MSFTNGP09.phx.gbl...
Try    Me.cm.EndCurrentEdit()    Me.lblInfo.Text = "Record Successfully Saved"    booDirty = FalseCatch ex As Exception    Me.lblInfo.Text = ex.MessageEnd Try This works for me. I have some columns that do not allow Nulls.  When I click save, if there is an error (a no-null is still DBNull.Value) it shows it to the user.  They can then fix it and click save and all is well.Explain your GUI to me a little better. Kevin  "Gary Shell" <gshell@fuse.net> wrote in message news:uN6ODfdaEHA.596@TK2MSFTNGP11.phx.gbl...> Yeah, I was a bit obtuse in my initial description.
     >
     > You are correct I could add code to check for the null first.  But I am
     > trying to figure out why the EndCurrentEdit clears the dataset's item
     > collection when an exception occurs.  I want to know what to expect when
     > some OTHER exception occurs, not just the one for this constraint.
     >
     > Gary
     >
     >
     > "a" <a@a.com> wrote in message
     > news:%231%23ozDdaEHA.556@tk2msftngp13.phx.gbl...
     > > Sorry, I thought you were gettin ghte error on the Update call, not the
     > > EndCurrentEdit..  Didn't know you had the constraint in the dataset.
     > >
     > > Why not perform the check in the GUI before the call to EndCurrentEdit?
     > >
     > > Kevin
     > >
     > > "Gary Shell" <gshell@fuse.net> wrote in message
     > > news:%231gacccaEHA.1248@TK2MSFTNGP11.phx.gbl...
     > > > I am bound to a dataset.  There is no relation in the dataset.  The
     > > > EndCurrentEdit does not make a trip to the server.  (only an UPDATE
     > method
     > > > would do that.)  The exception is actually occurring in the
     > EndCurrentEdit
     > > > because there is a No Nulls constraint on the column in question.  I've
     > > dug
     > > > into this a bit further and when the EndCurrentEdit is executed if the
     > > > exception occurs ALL of the data in the items collection for the new row
     > > is
     > > > set to "".    I don't understand why that should be.
     > > >
     > > > Gary
     > > >
     > > > "a" <a@a.com> wrote in message
     > > > news:%23FF0gWcaEHA.3480@TK2MSFTNGP11.phx.gbl...
     > > > > Post some code for this.  I am wondering a few things:  are you
     > binding
     > > to
     > > > > datasets?  Do you have the relation in the dataset?  That would let
     > you
     > > > > catch the violation prior to going to the server
     > > > > in the call to EndCurrentEdit.
     > > > >
     > > > > Kevin
     > > > >
     > > > >
     > > > >
     > > > >
     > > > > "Gary Shell" <gshell@fuse.net> wrote in message
     > > > > news:OlCz$ZbaEHA.2520@TK2MSFTNGP12.phx.gbl...
     > > > > > I have a simple data form that can edit and add records to a table.
     > > In
     > > > my
     > > > > > "OK Button" code I EndCurrentEdit and then perform a UPDATE method
     > on
     > > > the
     > > > > > data adapter.  It works just fine adding and editing data.
     > > > > >
     > > > > > One field on the table is a foreign key and I have referential
     > > integrity
     > > > > > enforced on the server.  When adding a new record I catch the
     > > exception
     > > > > > raised by the Update method if the user supplies invalid data and
     > > > display
     > > > > an
     > > > > > error message.  I then allow the user to fix the problem and hit the
     > > OK
     > > > > > button again.  The problem is when I get to the Update method again
     > > the
     > > > > > underlying row in the dataset seems to be no longer bound to my
     > > > controls.
     > > > > > That is, if I go in and look at the contents of the item collection
     > > for
     > > > > the
     > > > > > row being added the field that triggered the exception is still
     > null.
     > > > It
     > > > > > does not have the value in the control that the user just corrected.
     > > > > >
     > > > > > Is there something I need to tell the dataset or more likely the
     > data
     > > > > > adapter that we are "retrying" the update?
     > > > > >
     > > > > > Sign me somewhat confused, but impressed, by this .Net databinding.
     > > > > >
     > > > > > Gary
Gary Shell - 16 Jul 2004 02:35 GMT
One quick question, since I am binding the SelectedValue to my main table and the datasource, displaymember and valuemember to a "lookup" table am I really doing Complex binding?   (Obviously, I am confused by the difference.)

Thanks for this code.  If my idea posted in my other reply (temporarily turning off Constraint checking) does not pan out, I'll DEFINITELY use this.

Thanks again.

 Yeah . . . .  I neglected to see you are not using a CurrencyManager.

 That will solve all your problems (and may create new ones.)  I have a hard time getting the MS Solution to work in my live Apps.  In their solution, you would need to set your Non-Nullable field to something (0 or ""), otherwise you get the error on .Rows.Add(dr)

 The following does not work for all controls (checkbox deos not work), but it does work for TextBox and ComboBox:

 Public WithEvents cm As CurrencyManager

 Private Sub frmTaskEntry_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
       
 Me.cboType.DataBindings.Add(New System.Windows.Forms.Binding("SelectedValue", TaskData.Data.dsTaskData1, "tblTask.TypeRef"))
 Me.cboType.DataSource = TaskData.Data.dsTaskData1
 Me.cboType.DisplayMember = "tblType.Name"
 Me.cboType.ValueMember = "tblType.ID"

 cm = Me.BindingContext(TaskData.Data.dsTaskData1, "tblTask")

 cm.AddNew()

  ' USED TO PROGRAMMATICALLY SET A VALUE IN THE NEW ROW
         drv = CType(cm.Current, DataRowView)
         'Set ProjectRef
         drv.Item("ProjectRef") = intProjectRef
  cm.Refresh()

 End Sub

 Private Sub butSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butSave.Click
         Try
             Me.cm.EndCurrentEdit()
             Me.lblInfo.Text = "Record Successfully Saved"
             booDirty = False
         Catch ex As Exception
             Me.lblInfo.Text = ex.Message
         End Try
 End Sub

 '--------

 The
          drv = CType(cm.Current, DataRowView)
         'Set ProjectRef
         drv.Item("ProjectRef") = intProjectRef

 part needs to be done on columns bound to CheckBoxes, NumericUpDowns, DateTimePickers . . .

 Check out the CurrencyManager, which is the result of me.BindingContext when the binding is complex.

 Kevin

   "Gary Shell" <gshell@fuse.net> wrote in message news:ujIH7fraEHA.1000@TK2MSFTNGP12.phx.gbl...
   Another quick thought.  I wonder if this has anything to do with the fact that my AddNew procedure uses the technique described below.  I don' t add the new row to the bindingcontext.  I add it directly to the dataset.  This does seem to work OK when no exceptions are thrown.   But I wonder if when the exception IS thrown if the fact that the BindingContext didn't know I anything about the added row is causing the weirdness I see.

   Here's the pertinent text from a file found on Microsoft's site:

   However, these auto-generated programs have a major limitation. If the data being accessed has any fields that cannot be null (because the database schema does not allow nulls), then the program generated by the wizard will be unable to add records. When the Add button is pressed, an error message will indicate the first field in the record that is not allowed to be null. (If you don't have the latest service packs applied, you may not see the error message but the program will still refuse to add a record.)

   The problem is that the Data Form Wizard uses the BindingContext object to add a row to the bound DataTable. Here is the code that fails in the btnAdd_Click event routine:

Me.BindingContext(objProducts, "Products").AddNew()
The solution is to bypass the BindingContext object for new rows. Below is the typical code to add a new row. This code should replace the single line of code above:

Dim dr As DataRow
dr = objProducts.Tables("Products").NewRow
dr.Item("ProductName") = ""
dr.Item("Discontinued") = False
' Set any other fields that cannot null to default values.
objProducts.Tables("Products").Rows.Add(dr)
"Gary Shell" <gshell@fuse.net> wrote in message news:ubx868qaEHA.1764@TK2MSFTNGP10.phx.gbl...
     First let me say I'm glad we are still talking.  I was afraid I might have pissed you off in our exchange about crossposting.

     The GUI is pretty simple.  I will distill it further though to make this brief.  I have a text field called MetricName bound to txtMetricName.  I have a MetricClass field (with a no null constraint) bound to a combo box's SelectedValue property.  The list portion of the combo is bound to a table called MetricClasses.  There are a few other fields including a couple of booleans.  

     If I add a new record all fields on the form are blanked, as expected.  I then type a MetricName and NOTHING else, then hit my update code, the EndCurrentEdit method throws an exception about the null state of MetricClass, again as expected.

     I have a watch variable set to me.dsMetric.ItemArray and just before the EndCurrentEdit I can see the text I typed into the txtMetricName textbox in the correct ItemArray element.  (I can also see the contents of the other textboxes and checkboxes as well.)  But as soon as the EndCurrentEdit throws the exception, the entire ItemArray is reset.  By that I mean, all Items are cleared to a valid state for a new row, i.e.  all non-nullable fields are set to "", all nullable fields are set to null and all fields with declared default values have their correct defaults (only my booleans have default declared some true some false).  These same values from this ItemArray are also populated back to the bound controls, wiping out whatever I'd typed into the various text boxes.  

     What happens to your ItemArray after such an exception.  What happens to your form controls?  I'm desperately trying to figure out a way to preserve their state so I can retry the EndCurrentEdit.   That brings up a point, after your exception is thrown, and you click save a second time exactly what does your code do?  Does it do another EndCurrrentEdit and if that works you use an UPDATE method on the dataadapter?

     Hope this is a bit clearer.

     And thanks for sticking with me on this!!!!!!

     Gary
       "a" <a@a.com> wrote in message news:%23IWxKToaEHA.3508@TK2MSFTNGP09.phx.gbl...
Try    Me.cm.EndCurrentEdit()    Me.lblInfo.Text = "Record Successfully Saved"    booDirty = FalseCatch ex As Exception    Me.lblInfo.Text = ex.MessageEnd Try This works for me. I have some columns that do not allow Nulls.  When I click save, if there is an error (a no-null is still DBNull.Value) it shows it to the user.  They can then fix it and click save and all is well.Explain your GUI to me a little better. Kevin  "Gary Shell" <gshell@fuse.net> wrote in message news:uN6ODfdaEHA.596@TK2MSFTNGP11.phx.gbl...> Yeah, I was a bit obtuse in my initial description.
       >
       > You are correct I could add code to check for the null first.  But I am
       > trying to figure out why the EndCurrentEdit clears the dataset's item
       > collection when an exception occurs.  I want to know what to expect when
       > some OTHER exception occurs, not just the one for this constraint.
       >
       > Gary
       >
       >
       > "a" <a@a.com> wrote in message
       > news:%231%23ozDdaEHA.556@tk2msftngp13.phx.gbl...
       > > Sorry, I thought you were gettin ghte error on the Update call, not the
       > > EndCurrentEdit..  Didn't know you had the constraint in the dataset.
       > >
       > > Why not perform the check in the GUI before the call to EndCurrentEdit?
       > >
       > > Kevin
       > >
       > > "Gary Shell" <gshell@fuse.net> wrote in message
       > > news:%231gacccaEHA.1248@TK2MSFTNGP11.phx.gbl...
       > > > I am bound to a dataset.  There is no relation in the dataset.  The
       > > > EndCurrentEdit does not make a trip to the server.  (only an UPDATE
       > method
       > > > would do that.)  The exception is actually occurring in the
       > EndCurrentEdit
       > > > because there is a No Nulls constraint on the column in question.  I've
       > > dug
       > > > into this a bit further and when the EndCurrentEdit is executed if the
       > > > exception occurs ALL of the data in the items collection for the new row
       > > is
       > > > set to "".    I don't understand why that should be.
       > > >
       > > > Gary
       > > >
       > > > "a" <a@a.com> wrote in message
       > > > news:%23FF0gWcaEHA.3480@TK2MSFTNGP11.phx.gbl...
       > > > > Post some code for this.  I am wondering a few things:  are you
       > binding
       > > to
       > > > > datasets?  Do you have the relation in the dataset?  That would let
       > you
       > > > > catch the violation prior to going to the server
       > > > > in the call to EndCurrentEdit.
       > > > >
       > > > > Kevin
       > > > >
       > > > >
       > > > >
       > > > >
       > > > > "Gary Shell" <gshell@fuse.net> wrote in message
       > > > > news:OlCz$ZbaEHA.2520@TK2MSFTNGP12.phx.gbl...
       > > > > > I have a simple data form that can edit and add records to a table.
       > > In
       > > > my
       > > > > > "OK Button" code I EndCurrentEdit and then perform a UPDATE method
       > on
       > > > the
       > > > > > data adapter.  It works just fine adding and editing data.
       > > > > >
       > > > > > One field on the table is a foreign key and I have referential
       > > integrity
       > > > > > enforced on the server.  When adding a new record I catch the
       > > exception
       > > > > > raised by the Update method if the user supplies invalid data and
       > > > display
       > > > > an
       > > > > > error message.  I then allow the user to fix the problem and hit the
       > > OK
       > > > > > button again.  The problem is when I get to the Update method again
       > > the
       > > > > > underlying row in the dataset seems to be no longer bound to my
       > > > controls.
       > > > > > That is, if I go in and look at the contents of the item collection
       > > for
       > > > > the
       > > > > > row being added the field that triggered the exception is still
       > null.
       > > > It
       > > > > > does not have the value in the control that the user just corrected.
       > > > > >
       > > > > > Is there something I need to tell the dataset or more likely the
       > data
       > > > > > adapter that we are "retrying" the update?
       > > > > >
       > > > > > Sign me somewhat confused, but impressed, by this .Net databinding.
       > > > > >
       > > > > > Gary
Gary Shell - 16 Jul 2004 06:25 GMT
Well I fixed it and didn't have to resort to a currency manager at all!  My problems most assuredly were due to the stupid work around to the AddNew dilemma.  This workaround had me create my own data row and add it directly to the dataset bypassing the forms BindingContext.  I wanna shoot the person who came up with that fix.  Bypassing the BindingContext like that and then latter trying to use it to do the EndCurrentEdit and such is just plain STUPID!  My gut told me that from day one and I ignored my gut.  (Grumble, Grumble 32 hours of debugging time latter...)  Here is the scoop:

Turning off the Constraint test IS possible, there is a Dataset.EnbleConstraint property that controls that. But when I did turn it off, I got a weird error on the Me.BindingContext(me.dsMetric, "Metric").AddNew statement.  That error said "DataBinding could not find a row in the list that is suitable for all bindings".  

While doing a Google search on that error I uncovered a discussion about why the AddNew method was throwing an exception on the fields with a No Null constraint and as it turns out, it REALLY has nothing to do with those constraints at all.  The problem is with the Boolean fields defined in the same data set.  I know, I know that doesn't sound right.  Trust me.  Read this:http://groups.Google.com/groups?hl=en&lr=&ie=UTF-8&frame=right&thÕc90598e5d95dba
&seekm=eVR4w7tVDHA.2024%40TK2MSFTNGP12.phx.gbl#link6
 (scroll to message 6 in the thread),  (Sorry, I know that will word-wrap,  I don't know how to avoid that. If you can't read that: basically he said the problem is in the XSD definition of the data set.  He tells how to edit that XSD.)  Well, I thought what's another few minutes lost and tried what he suggested.  I added the default value info to the XML for each Boolean field in the schema.  I then got rid of my Dataset.EnableConstraints=off code and Voila! the AddNew worked just fine.  Ooooooooo. We're on to something here...  I can jettison the manual add of a new row to the underlying data set.  I won't have to bypass the BindingContext.  This is starting to sound better already.

So, next I went to my Commit code and change it to a simple
Me.BindingContext(Me.dsMetric, "Metric").EndCurrentEdit()
sqldaMetric.Update(Me.dsMetric)

Just like your code.  Well it worked!!!  I tried a new record and filled in my MetricName field and left my MetricClass field blank.  The EndCurrentEdit threw a No Nulls Allowed exception as expected and (trumpet flourish) LEFT MY DATASET AND CONTROLS CONTENTS INTACT!!!   Now I could go back to my form and all of the contents were still there. All I had to do was select a MetricClass from the dropdown and click my update button again.  My data was written to my SQLServer.  Whew!!!!!

Again, I was able to do this all using the forms own BindingContext.  Since IT created the new row, IT knew exactly how to keep my bound controls in sync.  What a surprise.  <grin>

Two other items.  First, I do have these controls on a tab page so I made sure in the FormLoad event I had a "tabPage.BindingContext = Me.BindingContext" for each tab page.  (Unsure, I added one for the actual TabControl itself as well, just for good measure.)  This apparently overcomes the problem of each container maintaining its own BindingContext.   (A case CAN be made to not do this, I realize.  But in most situations one is enough, I think.)

Second, I noticed an anomaly with the ComboBox.  If a ComboBox is programmatically populated and the user does not physically select a value, choosing to accept the displayed value, the BindingContext does not know to use this displayed value.  (I'm guessing that because the BindingContext gets no event notifying it of the data.)  On my form, I actually had a MetricClass and a MetricSubClass combobox. A selection in the Class causes a query of the data base to repopulate the SubClass combobox.  If I didn't ever click in the SubClass combobox, the EndEdit threw an No Nulls Exception about the MetricSubClass field.  Digging into the watch window I drilled down into the Binding Context and found it had a DataRowView.  So I declared my own DataRowView and set it to this one.  I could then drill down on that and found the itemarray.  Sure enough there was still a null there. So I added this:

'Get the context's actual DataRowView so we can manipulate it
theDataRowView = Me.BindingContext(Me.dsMetric, "Metric").Current
'now place the combobox selected values in to the appropriate item.
'Remember this DataRowView is a window directly into the
'BindingContext
theDataRowView.Item("MetricSubclass") = Me.cmbMetric_SubClass.SelectedValue

This made sure that the BindingContext knew about the content of the SubClass combobox.  

What a learning curve.  I was at a brick wall for 30 odd hours and suddenly the dam broke.

Hope some of this is helpful to you as well.

Thanks for the discussion.  It really helped give me some direction.

Gary



 One quick question, since I am binding the SelectedValue to my main table and the datasource, displaymember and valuemember to a "lookup" table am I really doing Complex binding?   (Obviously, I am confused by the difference.)

 Thanks for this code.  If my idea posted in my other reply (temporarily turning off Constraint checking) does not pan out, I'll DEFINITELY use this.

 Thanks again.

 Gary
   "a" <a@a.com> wrote in message news:OKS9H1raEHA.3204@TK2MSFTNGP09.phx.gbl...
   Yeah . . . .  I neglected to see you are not using a CurrencyManager.

   That will solve all your problems (and may create new ones.)  I have a hard time getting the MS Solution to work in my live Apps.  In their solution, you would need to set your Non-Nullable field to something (0 or ""), otherwise you get the error on .Rows.Add(dr)

   The following does not work for all controls (checkbox deos not work), but it does work for TextBox and ComboBox:

   Public WithEvents cm As CurrencyManager

   Private Sub frmTaskEntry_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
         
   Me.cboType.DataBindings.Add(New System.Windows.Forms.Binding("SelectedValue", TaskData.Data.dsTaskData1, "tblTask.TypeRef"))
   Me.cboType.DataSource = TaskData.Data.dsTaskData1
   Me.cboType.DisplayMember = "tblType.Name"
   Me.cboType.ValueMember = "tblType.ID"

   cm = Me.BindingContext(TaskData.Data.dsTaskData1, "tblTask")

   cm.AddNew()

    ' USED TO PROGRAMMATICALLY SET A VALUE IN THE NEW ROW
           drv = CType(cm.Current, DataRowView)
           'Set ProjectRef
           drv.Item("ProjectRef") = intProjectRef
    cm.Refresh()

   End Sub

   Private Sub butSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butSave.Click
           Try
               Me.cm.EndCurrentEdit()
               Me.lblInfo.Text = "Record Successfully Saved"
               booDirty = False
           Catch ex As Exception
               Me.lblInfo.Text = ex.Message
           End Try
   End Sub

   '--------

   The
            drv = CType(cm.Current, DataRowView)
           'Set ProjectRef
           drv.Item("ProjectRef") = intProjectRef

   part needs to be done on columns bound to CheckBoxes, NumericUpDowns, DateTimePickers . . .

   Check out the CurrencyManager, which is the result of me.BindingContext when the binding is complex.

   Kevin

     "Gary Shell" <gshell@fuse.net> wrote in message news:ujIH7fraEHA.1000@TK2MSFTNGP12.phx.gbl...
     Another quick thought.  I wonder if this has anything to do with the fact that my AddNew procedure uses the technique described below.  I don' t add the new row to the bindingcontext.  I add it directly to the dataset.  This does seem to work OK when no exceptions are thrown.   But I wonder if when the exception IS thrown if the fact that the BindingContext didn't know I anything about the added row is causing the weirdness I see.

     Here's the pertinent text from a file found on Microsoft's site:

     However, these auto-generated programs have a major limitation. If the data being accessed has any fields that cannot be null (because the database schema does not allow nulls), then the program generated by the wizard will be unable to add records. When the Add button is pressed, an error message will indicate the first field in the record that is not allowed to be null. (If you don't have the latest service packs applied, you may not see the error message but the program will still refuse to add a record.)

     The problem is that the Data Form Wizard uses the BindingContext object to add a row to the bound DataTable. Here is the code that fails in the btnAdd_Click event routine:

Me.BindingContext(objProducts, "Products").AddNew()
The solution is to bypass the BindingContext object for new rows. Below is the typical code to add a new row. This code should replace the single line of code above:

Dim dr As DataRow
dr = objProducts.Tables("Products").NewRow
dr.Item("ProductName") = ""
dr.Item("Discontinued") = False
' Set any other fields that cannot null to default values.
objProducts.Tables("Products").Rows.Add(dr)
"Gary Shell" <gshell@fuse.net> wrote in message news:ubx868qaEHA.1764@TK2MSFTNGP10.phx.gbl...
       First let me say I'm glad we are still talking.  I was afraid I might have pissed you off in our exchange about crossposting.

       The GUI is pretty simple.  I will distill it further though to make this brief.  I have a text field called MetricName bound to txtMetricName.  I have a MetricClass field (with a no null constraint) bound to a combo box's SelectedValue property.  The list portion of the combo is bound to a table called MetricClasses.  There are a few other fields including a couple of booleans.  

       If I add a new record all fields on the form are blanked, as expected.  I then type a MetricName and NOTHING else, then hit my update code, the EndCurrentEdit method throws an exception about the null state of MetricClass, again as expected.

       I have a watch variable set to me.dsMetric.ItemArray and just before the EndCurrentEdit I can see the text I typed into the txtMetricName textbox in the correct ItemArray element.  (I can also see the contents of the other textboxes and checkboxes as well.)  But as soon as the EndCurrentEdit throws the exception, the entire ItemArray is reset.  By that I mean, all Items are cleared to a valid state for a new row, i.e.  all non-nullable fields are set to "", all nullable fields are set to null and all fields with declared default values have their correct defaults (only my booleans have default declared some true some false).  These same values from this ItemArray are also populated back to the bound controls, wiping out whatever I'd typed into the various text boxes.  

       What happens to your ItemArray after such an exception.  What happens to your form controls?  I'm desperately trying to figure out a way to preserve their state so I can retry the EndCurrentEdit.   That brings up a point, after your exception is thrown, and you click save a second time exactly what does your code do?  Does it do another EndCurrrentEdit and if that works you use an UPDATE method on the dataadapter?

       Hope this is a bit clearer.

       And thanks for sticking with me on this!!!!!!

       Gary
         "a" <a@a.com> wrote in message news:%23IWxKToaEHA.3508@TK2MSFTNGP09.phx.gbl...
Try    Me.cm.EndCurrentEdit()    Me.lblInfo.Text = "Record Successfully Saved"    booDirty = FalseCatch ex As Exception    Me.lblInfo.Text = ex.MessageEnd Try This works for me. I have some columns that do not allow Nulls.  When I click save, if there is an error (a no-null is still DBNull.Value) it shows it to the user.  They can then fix it and click save and all is well.Explain your GUI to me a little better. Kevin  "Gary Shell" <gshell@fuse.net> wrote in message news:uN6ODfdaEHA.596@TK2MSFTNGP11.phx.gbl...> Yeah, I was a bit obtuse in my initial description.
         >
         > You are correct I could add code to check for the null first.  But I am
         > trying to figure out why the EndCurrentEdit clears the dataset's item
         > collection when an exception occurs.  I want to know what to expect when
         > some OTHER exception occurs, not just the one for this constraint.
         >
         > Gary
         >
         >
         > "a" <a@a.com> wrote in message
         > news:%231%23ozDdaEHA.556@tk2msftngp13.phx.gbl...
         > > Sorry, I thought you were gettin ghte error on the Update call, not the
         > > EndCurrentEdit..  Didn't know you had the constraint in the dataset.
         > >
         > > Why not perform the check in the GUI before the call to EndCurrentEdit?
         > >
         > > Kevin
         > >
         > > "Gary Shell" <gshell@fuse.net> wrote in message
         > > news:%231gacccaEHA.1248@TK2MSFTNGP11.phx.gbl...
         > > > I am bound to a dataset.  There is no relation in the dataset.  The
         > > > EndCurrentEdit does not make a trip to the server.  (only an UPDATE
         > method
         > > > would do that.)  The exception is actually occurring in the
         > EndCurrentEdit
         > > > because there is a No Nulls constraint on the column in question.  I've
         > > dug
         > > > into this a bit further and when the EndCurrentEdit is executed if the
         > > > exception occurs ALL of the data in the items collection for the new row
         > > is
         > > > set to "".    I don't understand why that should be.
         > > >
         > > > Gary
         > > >
         > > > "a" <a@a.com> wrote in message
         > > > news:%23FF0gWcaEHA.3480@TK2MSFTNGP11.phx.gbl...
         > > > > Post some code for this.  I am wondering a few things:  are you
         > binding
         > > to
         > > > > datasets?  Do you have the relation in the dataset?  That would let
         > you
         > > > > catch the violation prior to going to the server
         > > > > in the call to EndCurrentEdit.
         > > > >
         > > > > Kevin
         > > > >
         > > > >
         > > > >
         > > > >
         > > > > "Gary Shell" <gshell@fuse.net> wrote in message
         > > > > news:OlCz$ZbaEHA.2520@TK2MSFTNGP12.phx.gbl...
         > > > > > I have a simple data form that can edit and add records to a table.
         > > In
         > > > my
         > > > > > "OK Button" code I EndCurrentEdit and then perform a UPDATE method
         > on
         > > > the
         > > > > > data adapter.  It works just fine adding and editing data.
         > > > > >
         > > > > > One field on the table is a foreign key and I have referential
         > > integrity
         > > > > > enforced on the server.  When adding a new record I catch the
         > > exception
         > > > > > raised by the Update method if the user supplies invalid data and
         > > > display
         > > > > an
         > > > > > error message.  I then allow the user to fix the problem and hit the
         > > OK
         > > > > > button again.  The problem is when I get to the Update method again
         > > the
         > > > > > underlying row in the dataset seems to be no longer bound to my
         > > > controls.
         > > > > > That is, if I go in and look at the contents of the item collection
         > > for
         > > > > the
         > > > > > row being added the field that triggered the exception is still
         > null.
         > > > It
         > > > > > does not have the value in the control that the user just corrected.
         > > > > >
         > > > > > Is there something I need to tell the dataset or more likely the
         > data
         > > > > > adapter that we are "retrying" the update?
         > > > > >
         > > > > > Sign me somewhat confused, but impressed, by this .Net databinding.
         > > > > >
         > > > > > Gary
a - 16 Jul 2004 17:49 GMT
You ARE resorting to a CurrencyManager.

It's like this:  BindingManagerBase is a BaseClass with 2 implementations, CurrencyManager and PropertyManager.  Simple Binding (properties) results in a PropertyManager. Complex Binding (list) results in a CurrencyManager.

me.BindingContext(...) will Either be a PM or a CM, depending on the type of binding.

Me.BindingContext(me.dsMetric, "Metric").AddNew

is the same as

dim cm as CurrencyManager
cm = Me.BindingContext(me.dsMetric, "Metric")
cm.addnew

Just wanted to provide some more info.  It helped me when I understood what was going on here.

As you noticed, to set the Value in code, Get the DataRowView from the CurrencyManager, and set it. You MAY have to call CM.Refresh to display the data in a bound control.

The Validate of the control is what triggers the data to go to the Underlying datasource, so clicking the combobox, (or setting the focus), can work too.

NOTE:  The tweak you did in the XSD does not Serialize, as far as I can tell . . . . So, that solution does not work if you are consuming a WebService. (WSDL does not set the NullValue property)  I had a multiple-day experience like your own figuring that out.

Kevin
 Well I fixed it and didn't have to resort to a currency manager at all!  My problems most assuredly were due to the stupid work around to the AddNew dilemma.  This workaround had me create my own data row and add it directly to the dataset bypassing the forms BindingContext.  I wanna shoot the person who came up with that fix.  Bypassing the BindingContext like that and then latter trying to use it to do the EndCurrentEdit and such is just plain STUPID!  My gut told me that from day one and I ignored my gut.  (Grumble, Grumble 32 hours of debugging time latter...)  Here is the scoop:

 Turning off the Constraint test IS possible, there is a Dataset.EnbleConstraint property that controls that. But when I did turn it off, I got a weird error on the Me.BindingContext(me.dsMetric, "Metric").AddNew statement.  That error said "DataBinding could not find a row in the list that is suitable for all bindings".  

 While doing a Google search on that error I uncovered a discussion about why the AddNew method was throwing an exception on the fields with a No Null constraint and as it turns out, it REALLY has nothing to do with those constraints at all.  The problem is with the Boolean fields defined in the same data set.  I know, I know that doesn't sound right.  Trust me.  Read this:http://groups.Google.com/groups?hl=en&lr=&ie=UTF-8&frame=right&thÕc90598e5d95dba
&seekm=eVR4w7tVDHA.2024%40TK2MSFTNGP12.phx.gbl#link6
 (scroll to message 6 in the thread),  (Sorry, I know that will word-wrap,  I don't know how to avoid that. If you can't read that: basically he said the problem is in the XSD definition of the data set.  He tells how to edit that XSD.)  Well, I thought what's another few minutes lost and tried what he suggested.  I added the default value info to the XML for each Boolean field in the schema.  I then got rid of my Dataset.EnableConstraints=off code and Voila! the AddNew worked just fine.  Ooooooooo. We're on to something here...  I can jettison the manual add of a new row to the underlying data set.  I won't have to bypass the BindingContext.  This is starting to sound better already.

 So, next I went to my Commit code and change it to a simple
 Me.BindingContext(Me.dsMetric, "Metric").EndCurrentEdit()
 sqldaMetric.Update(Me.dsMetric)

 Just like your code.  Well it worked!!!  I tried a new record and filled in my MetricName field and left my MetricClass field blank.  The EndCurrentEdit threw a No Nulls Allowed exception as expected and (trumpet flourish) LEFT MY DATASET AND CONTROLS CONTENTS INTACT!!!   Now I could go back to my form and all of the contents were still there. All I had to do was select a MetricClass from the dropdown and click my update button again.  My data was written to my SQLServer.  Whew!!!!!

 Again, I was able to do this all using the forms own BindingContext.  Since IT created the new row, IT knew exactly how to keep my bound controls in sync.  What a surprise.  <grin>

 Two other items.  First, I do have these controls on a tab page so I made sure in the FormLoad event I had a "tabPage.BindingContext = Me.BindingContext" for each tab page.  (Unsure, I added one for the actual TabControl itself as well, just for good measure.)  This apparently overcomes the problem of each container maintaining its own BindingContext.   (A case CAN be made to not do this, I realize.  But in most situations one is enough, I think.)

 Second, I noticed an anomaly with the ComboBox.  If a ComboBox is programmatically populated and the user does not physically select a value, choosing to accept the displayed value, the BindingContext does not know to use this displayed value.  (I'm guessing that because the BindingContext gets no event notifying it of the data.)  On my form, I actually had a MetricClass and a MetricSubClass combobox. A selection in the Class causes a query of the data base to repopulate the SubClass combobox.  If I didn't ever click in the SubClass combobox, the EndEdit threw an No Nulls Exception about the MetricSubClass field.  Digging into the watch window I drilled down into the Binding Context and found it had a DataRowView.  So I declared my own DataRowView and set it to this one.  I could then drill down on that and found the itemarray.  Sure enough there was still a null there. So I added this:

 'Get the context's actual DataRowView so we can manipulate it
 theDataRowView = Me.BindingContext(Me.dsMetric, "Metric").Current
 'now place the combobox selected values in to the appropriate item.
 'Remember this DataRowView is a window directly into the
 'BindingContext
 theDataRowView.Item("MetricSubclass") = Me.cmbMetric_SubClass.SelectedValue

 This made sure that the BindingContext knew about the content of the SubClass combobox.  

 What a learning curve.  I was at a brick wall for 30 odd hours and suddenly the dam broke.

 Hope some of this is helpful to you as well.

 Thanks for the discussion.  It really helped give me some direction.

 Gary

 "Gary Shell" <gshell@fuse.net> wrote in message news:uombCVtaEHA.3996@TK2MSFTNGP12.phx.gbl...
   One quick question, since I am binding the SelectedValue to my main table and the datasource, displaymember and valuemember to a "lookup" table am I really doing Complex binding?   (Obviously, I am confused by the difference.)

   Thanks for this code.  If my idea posted in my other reply (temporarily turning off Constraint checking) does not pan out, I'll DEFINITELY use this.

   Thanks again.

   Gary
     "a" <a@a.com> wrote in message news:OKS9H1raEHA.3204@TK2MSFTNGP09.phx.gbl...
     Yeah . . . .  I neglected to see you are not using a CurrencyManager.

     That will solve all your problems (and may create new ones.)  I have a hard time getting the MS Solution to work in my live Apps.  In their solution, you would need to set your Non-Nullable field to something (0 or ""), otherwise you get the error on .Rows.Add(dr)

     The following does not work for all controls (checkbox deos not work), but it does work for TextBox and ComboBox:

     Public WithEvents cm As CurrencyManager

     Private Sub frmTaskEntry_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
           
     Me.cboType.DataBindings.Add(New System.Windows.Forms.Binding("SelectedValue", TaskData.Data.dsTaskData1, "tblTask.TypeRef"))
     Me.cboType.DataSource = TaskData.Data.dsTaskData1
     Me.cboType.DisplayMember = "tblType.Name"
     Me.cboType.ValueMember = "tblType.ID"

     cm = Me.BindingContext(TaskData.Data.dsTaskData1, "tblTask")

     cm.AddNew()

      ' USED TO PROGRAMMATICALLY SET A VALUE IN THE NEW ROW
             drv = CType(cm.Current, DataRowView)
             'Set ProjectRef
             drv.Item("ProjectRef") = intProjectRef
      cm.Refresh()

     End Sub

     Private Sub butSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butSave.Click
             Try
                 Me.cm.EndCurrentEdit()
                 Me.lblInfo.Text = "Record Successfully Saved"
                 booDirty = False
             Catch ex As Exception
                 Me.lblInfo.Text = ex.Message
             End Try
     End Sub

     '--------

     The
              drv = CType(cm.Current, DataRowView)
             'Set ProjectRef
             drv.Item("ProjectRef") = intProjectRef

     part needs to be done on columns bound to CheckBoxes, NumericUpDowns, DateTimePickers . . .

     Check out the CurrencyManager, which is the result of me.BindingContext when the binding is complex.

     Kevin

       "Gary Shell" <gshell@fuse.net> wrote in message news:ujIH7fraEHA.1000@TK2MSFTNGP12.phx.gbl...
       Another quick thought.  I wonder if this has anything to do with the fact that my AddNew procedure uses the technique described below.  I don' t add the new row to the bindingcontext.  I add it directly to the dataset.  This does seem to work OK when no exceptions are thrown.   But I wonder if when the exception IS thrown if the fact that the BindingContext didn't know I anything about the added row is causing the weirdness I see.

       Here's the pertinent text from a file found on Microsoft's site:

       However, these auto-generated programs have a major limitation. If the data being accessed has any fields that cannot be null (because the database schema does not allow nulls), then the program generated by the wizard will be unable to add records. When the Add button is pressed, an error message will indicate the first field in the record that is not allowed to be null. (If you don't have the latest service packs applied, you may not see the error message but the program will still refuse to add a record.)

       The problem is that the Data Form Wizard uses the BindingContext object to add a row to the bound DataTable. Here is the code that fails in the btnAdd_Click event routine:

Me.BindingContext(objProducts, "Products").AddNew()
The solution is to bypass the BindingContext object for new rows. Below is the typical code to add a new row. This code should replace the single line of code above:

Dim dr As DataRow
dr = objProducts.Tables("Products").NewRow
dr.Item("ProductName") = ""
dr.Item("Discontinued") = False
' Set any other fields that cannot null to default values.
objProducts.Tables("Products").Rows.Add(dr)
"Gary Shell" <gshell@fuse.net> wrote in message news:ubx868qaEHA.1764@TK2MSFTNGP10.phx.gbl...
         First let me say I'm glad we are still talking.  I was afraid I might have pissed you off in our exchange about crossposting.

         The GUI is pretty simple.  I will distill it further though to make this brief.  I have a text field called MetricName bound to txtMetricName.  I have a MetricClass field (with a no null constraint) bound to a combo box's SelectedValue property.  The list portion of the combo is bound to a table called MetricClasses.  There are a few other fields including a couple of booleans.  

         If I add a new record all fields on the form are blanked, as expected.  I then type a MetricName and NOTHING else, then hit my update code, the EndCurrentEdit method throws an exception about the null state of MetricClass, again as expected.

         I have a watch variable set to me.dsMetric.ItemArray and just before the EndCurrentEdit I can see the text I typed into the txtMetricName textbox in the correct ItemArray element.  (I can also see the contents of the other textboxes and checkboxes as well.)  But as soon as the EndCurrentEdit throws the exception, the entire ItemArray is reset.  By that I mean, all Items are cleared to a valid state for a new row, i.e.  all non-nullable fields are set to "", all nullable fields are set to null and all fields with declared default values have their correct defaults (only my booleans have default declared some true some false).  These same values from this ItemArray are also populated back to the bound controls, wiping out whatever I'd typed into the various text boxes.  

         What happens to your ItemArray after such an exception.  What happens to your form controls?  I'm desperately trying to figure out a way to preserve their state so I can retry the EndCurrentEdit.   That brings up a point, after your exception is thrown, and you click save a second time exactly what does your code do?  Does it do another EndCurrrentEdit and if that works you use an UPDATE method on the dataadapter?

         Hope this is a bit clearer.

         And thanks for sticking with me on this!!!!!!

         Gary
           "a" <a@a.com> wrote in message news:%23IWxKToaEHA.3508@TK2MSFTNGP09.phx.gbl...
Try    Me.cm.EndCurrentEdit()    Me.lblInfo.Text = "Record Successfully Saved"    booDirty = FalseCatch ex As Exception    Me.lblInfo.Text = ex.MessageEnd Try This works for me. I have some columns that do not allow Nulls.  When I click save, if there is an error (a no-null is still DBNull.Value) it shows it to the user.  They can then fix it and click save and all is well.Explain your GUI to me a little better. Kevin  "Gary Shell" <gshell@fuse.net> wrote in message news:uN6ODfdaEHA.596@TK2MSFTNGP11.phx.gbl...> Yeah, I was a bit obtuse in my initial description.
           >
           > You are correct I could add code to check for the null first.  But I am
           > trying to figure out why the EndCurrentEdit clears the dataset's item
           > collection when an exception occurs.  I want to know what to expect when
           > some OTHER exception occurs, not just the one for this constraint.
           >
           > Gary
           >
           >
           > "a" <a@a.com> wrote in message
           > news:%231%23ozDdaEHA.556@tk2msftngp13.phx.gbl...
           > > Sorry, I thought you were gettin ghte error on the Update call, not the
           > > EndCurrentEdit..  Didn't know you had the constraint in the dataset.
           > >
           > > Why not perform the check in the GUI before the call to EndCurrentEdit?
           > >
           > > Kevin
           > >
           > > "Gary Shell" <gshell@fuse.net> wrote in message
           > > news:%231gacccaEHA.1248@TK2MSFTNGP11.phx.gbl...
           > > > I am bound to a dataset.  There is no relation in the dataset.  The
           > > > EndCurrentEdit does not make a trip to the server.  (only an UPDATE
           > method
           > > > would do that.)  The exception is actually occurring in the
           > EndCurrentEdit
           > > > because there is a No Nulls constraint on the column in question.  I've
           > > dug
           > > > into this a bit further and when the EndCurrentEdit is executed if the
           > > > exception occurs ALL of the data in the items collection for the new row
           > > is
           > > > set to "".    I don't understand why that should be.
           > > >
           > > > Gary
           > > >
           > > > "a" <a@a.com> wrote in message
           > > > news:%23FF0gWcaEHA.3480@TK2MSFTNGP11.phx.gbl...
           > > > > Post some code for this.  I am wondering a few things:  are you
           > binding
           > > to
           > > > > datasets?  Do you have the relation in the dataset?  That would let
           > you
           > > > > catch the violation prior to going to the server
           > > > > in the call to EndCurrentEdit.
           > > > >
           > > > > Kevin
           > > > >
           > > > >
           > > > >
           > > > >
           > > > > "Gary Shell" <gshell@fuse.net> wrote in message
           > > > > news:OlCz$ZbaEHA.2520@TK2MSFTNGP12.phx.gbl...
           > > > > > I have a simple data form that can edit and add records to a table.
           > > In
           > > > my
           > > > > > "OK Button" code I EndCurrentEdit and then perform a UPDATE method
           > on
           > > > the
           > > > > > data adapter.  It works just fine adding and editing data.
           > > > > >
           > > > > > One field on the table is a foreign key and I have referential
           > > integrity
           > > > > > enforced on the server.  When adding a new record I catch the
           > > exception
           > > > > > raised by the Update method if the user supplies invalid data and
           > > > display
           > > > > an
           > > > > > error message.  I then allow the user to fix the problem and hit the
           > > OK
           > > > > > button again.  The problem is when I get to the Update method again
           > > the
           > > > > > underlying row in the dataset seems to be no longer bound to my
           > > > controls.
           > > > > > That is, if I go in and look at the contents of the item collection
           > > for
           > > > > the
           > > > > > row being added the field that triggered the exception is still
           > null.
           > > > It
           > > > > > does not have the value in the control that the user just corrected.
           > > > > >
           > > > > > Is there something I need to tell the dataset or more likely the
           > data
           > > > > > adapter that we are "retrying" the update?
           > > > > >
           > > > > > Sign me somewhat confused, but impressed, by this .Net databinding.
           > > > > >
           > > > > > Gary
Gary Shell - 16 Jul 2004 18:35 GMT
You are right I am using a CurrencyManager, I realized I should have said I didn't have to explicitly reference it I was able to use the "default" one.

It took me a while to figure out how to set that Value in code.  But boy oh boy, did it open my eyes as to how all this "object stuff" really works.  I've only been using VB.Net for a month, but have been a VB user since the very first beta (aka ThunderForm if my memory serves me).    It didn't appear that I did need to call the CM.Refresh, my data did display.  In fact it was displayed all along.   But I just realized that if I set the data in the CM to something different than was displayed at the time, I might need to do this refresh.  Thanks, I'll TRY to remember that for future use.  <grin>

Since the Validate of the control actually what triggers the data to go to the dataset, is there any downside to the way I did it, or should I change my code to just set focus to each combobox to make sure they send their data to the dataset?

I am not consuming any WebServices in this app, nor will it in the future.  So the "tweak" should suffice for now.  However, if that tweak can't be used as you indicated what is the CORRECT way to get around the issue of the Boolean fields causing a "No Nulls" exception on other fields when invoking an AddNew method on the BindingContext?  Obviously, the widely published method of bypassing the BindingContext and adding your own row to the associated dataset is NOT usable.  I now know what havoc it will cause when exceptions are thrown on the subsequent EndCurrentEdit.  I wonder how many other poor souls have been bitten by this supposed workaround?  I'm betting hundreds of folks!

Again thank you so much for this discourse.  It proves it is possible for an old dog to learn new tricks.  <big ol' grin>

 You ARE resorting to a CurrencyManager.

 It's like this:  BindingManagerBase is a BaseClass with 2 implementations, CurrencyManager and PropertyManager.  Simple Binding (properties) results in a PropertyManager. Complex Binding (list) results in a CurrencyManager.

 me.BindingContext(...) will Either be a PM or a CM, depending on the type of binding.

 Me.BindingContext(me.dsMetric, "Metric").AddNew

 is the same as

 dim cm as CurrencyManager
 cm = Me.BindingContext(me.dsMetric, "Metric")
 cm.addnew

 Just wanted to provide some more info.  It helped me when I understood what was going on here.

 As you noticed, to set the Value in code, Get the DataRowView from the CurrencyManager, and set it. You MAY have to call CM.Refresh to display the data in a bound control.

 The Validate of the control is what triggers the data to go to the Underlying datasource, so clicking the combobox, (or setting the focus), can work too.

 NOTE:  The tweak you did in the XSD does not Serialize, as far as I can tell . . . . So, that solution does not work if you are consuming a WebService. (WSDL does not set the NullValue property)  I had a multiple-day experience like your own figuring that out.

 Kevin
   "Gary Shell" <gshell@fuse.net> wrote in message news:OX%23hgVvaEHA.2016@TK2MSFTNGP09.phx.gbl...
   Well I fixed it and didn't have to resort to a currency manager at all!  My problems most assuredly were due to the stupid work around to the AddNew dilemma.  This workaround had me create my own data row and add it directly to the dataset bypassing the forms BindingContext.  I wanna shoot the person who came up with that fix.  Bypassing the BindingContext like that and then latter trying to use it to do the EndCurrentEdit and such is just plain STUPID!  My gut told me that from day one and I ignored my gut.  (Grumble, Grumble 32 hours of debugging time latter...)  Here is the scoop:

   Turning off the Constraint test IS possible, there is a Dataset.EnbleConstraint property that controls that. But when I did turn it off, I got a weird error on the Me.BindingContext(me.dsMetric, "Metric").AddNew statement.  That error said "DataBinding could not find a row in the list that is suitable for all bindings".  

   While doing a Google search on that error I uncovered a discussion about why the AddNew method was throwing an exception on the fields with a No Null constraint and as it turns out, it REALLY has nothing to do with those constraints at all.  The problem is with the Boolean fields defined in the same data set.  I know, I know that doesn't sound right.  Trust me.  Read this:http://groups.Google.com/groups?hl=en&lr=&ie=UTF-8&frame=right&thÕc90598e5d95dba
&seekm=eVR4w7tVDHA.2024%40TK2MSFTNGP12.phx.gbl#link6
 (scroll to message 6 in the thread),  (Sorry, I know that will word-wrap,  I don't know how to avoid that. If you can't read that: basically he said the problem is in the XSD definition of the data set.  He tells how to edit that XSD.)  Well, I thought what's another few minutes lost and tried what he suggested.  I added the default value info to the XML for each Boolean field in the schema.  I then got rid of my Dataset.EnableConstraints=off code and Voila! the AddNew worked just fine.  Ooooooooo. We're on to something here...  I can jettison the manual add of a new row to the underlying data set.  I won't have to bypass the BindingContext.  This is starting to sound better already.

   So, next I went to my Commit code and change it to a simple
   Me.BindingContext(Me.dsMetric, "Metric").EndCurrentEdit()
   sqldaMetric.Update(Me.dsMetric)

   Just like your code.  Well it worked!!!  I tried a new record and filled in my MetricName field and left my MetricClass field blank.  The EndCurrentEdit threw a No Nulls Allowed exception as expected and (trumpet flourish) LEFT MY DATASET AND CONTROLS CONTENTS INTACT!!!   Now I could go back to my form and all of the contents were still there. All I had to do was select a MetricClass from the dropdown and click my update button again.  My data was written to my SQLServer.  Whew!!!!!

   Again, I was able to do this all using the forms own BindingContext.  Since IT created the new row, IT knew exactly how to keep my bound controls in sync.  What a surprise.  <grin>

   Two other items.  First, I do have these controls on a tab page so I made sure in the FormLoad event I had a "tabPage.BindingContext = Me.BindingContext" for each tab page.  (Unsure, I added one for the actual TabControl itself as well, just for good measure.)  This apparently overcomes the problem of each container maintaining its own BindingContext.   (A case CAN be made to not do this, I realize.  But in most situations one is enough, I think.)

   Second, I noticed an anomaly with the ComboBox.  If a ComboBox is programmatically populated and the user does not physically select a value, choosing to accept the displayed value, the BindingContext does not know to use this displayed value.  (I'm guessing that because the BindingContext gets no event notifying it of the data.)  On my form, I actually had a MetricClass and a MetricSubClass combobox. A selection in the Class causes a query of the data base to repopulate the SubClass combobox.  If I didn't ever click in the SubClass combobox, the EndEdit threw an No Nulls Exception about the MetricSubClass field.  Digging into the watch window I drilled down into the Binding Context and found it had a DataRowView.  So I declared my own DataRowView and set it to this one.  I could then drill down on that and found the itemarray.  Sure enough there was still a null there. So I added this:

   'Get the context's actual DataRowView so we can manipulate it
   theDataRowView = Me.BindingContext(Me.dsMetric, "Metric").Current
   'now place the combobox selected values in to the appropriate item.
   'Remember this DataRowView is a window directly into the
   'BindingContext
   theDataRowView.Item("MetricSubclass") = Me.cmbMetric_SubClass.SelectedValue

   This made sure that the BindingContext knew about the content of the SubClass combobox.  

   What a learning curve.  I was at a brick wall for 30 odd hours and suddenly the dam broke.

   Hope some of this is helpful to you as well.

   Thanks for the discussion.  It really helped give me some direction.

   Gary

   "Gary Shell" <gshell@fuse.net> wrote in message news:uombCVtaEHA.3996@TK2MSFTNGP12.phx.gbl...
     One quick question, since I am binding the SelectedValue to my main table and the datasource, displaymember and valuemember to a "lookup" table am I really doing Complex binding?   (Obviously, I am confused by the difference.)

     Thanks for this code.  If my idea posted in my other reply (temporarily turning off Constraint checking) does not pan out, I'll DEFINITELY use this.

     Thanks again.

     Gary
       "a" <a@a.com> wrote in message news:OKS9H1raEHA.3204@TK2MSFTNGP09.phx.gbl...
       Yeah . . . .  I neglected to see you are not using a CurrencyManager.

       That will solve all your problems (and may create new ones.)  I have a hard time getting the MS Solution to work in my live Apps.  In their solution, you would need to set your Non-Nullable field to something (0 or ""), otherwise you get the error on .Rows.Add(dr)

       The following does not work for all controls (checkbox deos not work), but it does work for TextBox and ComboBox:

       Public WithEvents cm As CurrencyManager

       Private Sub frmTaskEntry_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
             
       Me.cboType.DataBindings.Add(New System.Windows.Forms.Binding("SelectedValue", TaskData.Data.dsTaskData1, "tblTask.TypeRef"))
       Me.cboType.DataSource = TaskData.Data.dsTaskData1
       Me.cboType.DisplayMember = "tblType.Name"
       Me.cboType.ValueMember = "tblType.ID"

       cm = Me.BindingContext(TaskData.Data.dsTaskData1, "tblTask")

       cm.AddNew()

        ' USED TO PROGRAMMATICALLY SET A VALUE IN THE NEW ROW
               drv = CType(cm.Current, DataRowView)
               'Set ProjectRef
               drv.Item("ProjectRef") = intProjectRef
        cm.Refresh()

       End Sub

       Private Sub butSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butSave.Click
               Try
                   Me.cm.EndCurrentEdit()
                   Me.lblInfo.Text = "Record Successfully Saved"
                   booDirty = False
               Catch ex As Exception
                   Me.lblInfo.Text = ex.Message
               End Try
       End Sub

       '--------

       The
                drv = CType(cm.Current, DataRowView)
               'Set ProjectRef
               drv.Item("ProjectRef") = intProjectRef

       part needs to be done on columns bound to CheckBoxes, NumericUpDowns, DateTimePickers . . .

       Check out the CurrencyManager, which is the result of me.BindingContext when the binding is complex.

       Kevin

         "Gary Shell" <gshell@fuse.net> wrote in message news:ujIH7fraEHA.1000@TK2MSFTNGP12.phx.gbl...
         Another quick thought.  I wonder if this has anything to do with the fact that my AddNew procedure uses the technique described below.  I don' t add the new row to the bindingcontext.  I add it directly to the dataset.  This does seem to work OK when no exceptions are thrown.   But I wonder if when the exception IS thrown if the fact that the BindingContext didn't know I anything about the added row is causing the weirdness I see.

         Here's the pertinent text from a file found on Microsoft's site:

         However, these auto-generated programs have a major limitation. If the data being accessed has any fields that cannot be null (because the database schema does not allow nulls), then the program generated by the wizard will be unable to add records. When the Add button is pressed, an error message will indicate the first field in the record that is not allowed to be null. (If you don't have the latest service packs applied, you may not see the error message but the program will still refuse to add a record.)

         The problem is that the Data Form Wizard uses the BindingContext object to add a row to the bound DataTable. Here is the code that fails in the btnAdd_Click event routine:

Me.BindingContext(objProducts, "Products").AddNew()
The solution is to bypass the BindingContext object for new rows. Below is the typical code to add a new row. This code should replace the single line of code above:

Dim dr As DataRow
dr = objProducts.Tables("Products").NewRow
dr.Item("ProductName") = ""
dr.Item("Discontinued") = False
' Set any other fields that cannot null to default values.
objProducts.Tables("Products").Rows.Add(dr)
"Gary Shell" <gshell@fuse.net> wrote in message news:ubx868qaEHA.1764@TK2MSFTNGP10.phx.gbl...
           First let me say I'm glad we are still talking.  I was afraid I might have pissed you off in our exchange about crossposting.

           The GUI is pretty simple.  I will distill it further though to make this brief.  I have a text field called MetricName bound to txtMetricName.  I have a MetricClass field (with a no null constraint) bound to a combo box's SelectedValue property.  The list portion of the combo is bound to a table called MetricClasses.  There are a few other fields including a couple of booleans.  

           If I add a new record all fields on the form are blanked, as expected.  I then type a MetricName and NOTHING else, then hit my update code, the EndCurrentEdit method throws an exception about the null state of MetricClass, again as expected.

           I have a watch variable set to me.dsMetric.ItemArray and just before the EndCurrentEdit I can see the text I typed into the txtMetricName textbox in the correct ItemArray element.  (I can also see the contents of the other textboxes and checkboxes as well.)  But as soon as the EndCurrentEdit throws the exception, the entire ItemArray is reset.  By that I mean, all Items are cleared to a valid state for a new row, i.e.  all non-nullable fields are set to "", all nullable fields are set to null and all fields with declared default values have their correct defaults (only my booleans have default declared some true some false).  These same values from this ItemArray are also populated back to the bound controls, wiping out whatever I'd typed into the various text boxes.  

           What happens to your ItemArray after such an exception.  What happens to your form controls?  I'm desperately trying to figure out a way to preserve their state so I can retry the EndCurrentEdit.   That brings up a point, after your exception is thrown, and you click save a second time exactly what does your code do?  Does it do another EndCurrrentEdit and if that works you use an UPDATE method on the dataadapter?

           Hope this is a bit clearer.

           And thanks for sticking with me on this!!!!!!

           Gary
             "a" <a@a.com> wrote in message news:%23IWxKToaEHA.3508@TK2MSFTNGP09.phx.gbl...
Try    Me.cm.EndCurrentEdit()    Me.lblInfo.Text = "Record Successfully Saved"    booDirty = FalseCatch ex As Exception    Me.lblInfo.Text = ex.MessageEnd Try This works for me. I have some columns that do not allow Nulls.  When I click save, if there is an error (a no-null is still DBNull.Value) it shows it to the user.  They can then fix it and click save and all is well.Explain your GUI to me a little better. Kevin  "Gary Shell" <gshell@fuse.net> wrote in message news:uN6ODfdaEHA.596@TK2MSFTNGP11.phx.gbl...> Yeah, I was a bit obtuse in my initial description.
             >
             > You are correct I could add code to check for the null first.  But I am
             > trying to figure out why the EndCurrentEdit clears the dataset's item
             > collection when an exception occurs.  I want to know what to expect when
             > some OTHER exception occurs, not just the one for this constraint.
             >
             > Gary
             >
             >
             > "a" <a@a.com> wrote in message
             > news:%231%23ozDdaEHA.556@tk2msftngp13.phx.gbl...
             > > Sorry, I thought you were gettin ghte error on the Update call, not the
             > > EndCurrentEdit..  Didn't know you had the constraint in the dataset.
             > >
             > > Why not perform the check in the GUI before the call to EndCurrentEdit?
             > >
             > > Kevin
             > >
             > > "Gary Shell" <gshell@fuse.net> wrote in message
             > > news:%231gacccaEHA.1248@TK2MSFTNGP11.phx.gbl...
             > > > I am bound to a dataset.  There is no relation in the dataset.  The
             > > > En