Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

passing a bindingsource to an update form

Status
Not open for further replies.

wt2

Programmer
Dec 29, 2006
4
US
Hello.

I have a VB.Net application with two forms. The first form consists of a grid that is bound to a datasource. If the user double-clicks a row in the grid, the second form then displays the values of the selected row in bound textboxes which allow for updating or deleting the record. This is accomplished by passing a bindingsource to the detail form via a .showdialog() call and binding all the textboxes to the passed in bindingsource. This functionality is working with no problems.

The problem I'm having is with adding new records to the underlying datatable using the same detail form. The first form has an "Add New Record" button that also calls the detail form.

Specifically, the problem is that when I call bindingSource.AddNew on the detail form, I get an error because non-string fields are not allowing a new row to be created if they contain null values (which seems to be the default when .AddNew is called). I've been able to work around this by inserting (using a dataRowView) 0's for integer fields and some arbitrary date for date fields but it seems like there must be a better way to do this. I don't like this approach because these temporary values are then displayed in the various textboxes. All of this processing is being done before the form is displayed and before the user enters any values to be inserted.

It would be very helpful if you could post a simple example of passing a bindingsource into a form that can both add and edit records.

Thanks very much for any assistance you can provide.

 
When you call AddNew it implicitly calls an EndEdit on any outstanding edits in progress. If any of the non-nullable fields do not have appropriate data, the error will be thrown. This can happen if you call AddNew twice. The second call does an EndEdit on the first call, and the error is thrown.

Check your code to make sure you aren't somehow calling AddNew twice. If that's not it, post back and we'll look at other possibilities.



I used to rock and roll every night and party every day. Then it was every other day. Now I'm lucky if I can find 30 minutes a week in which to get funky. - Homer Simpson

Arrrr, mateys! Ye needs ta be preparin' yerselves fer Talk Like a Pirate Day! Ye has a choice: talk like a pira
 
thanks for your quick reply. i checked my code and i do not see other calls to .addnew. I do have a call to .AllowNew = true right before my call to .addnew. I tried to remove the first call but still received the same error. I also added a specific call to .EndEdit before I call .addnew.

here's some of the relevant code from the detail form:

Public Sub New(ByVal bSource As BindingSource, ByVal updateMode As String)
saveBindingSource = bSource
saveUpdateMode = updateMode ' "add" or "edit"
saveBindingSource.EndEdit()
InitializeComponent()
End Sub

Private Sub CompanyDetails_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

If saveUpdateMode = "add" Then
saveBindingSource.AllowNew = True
saveBindingSource.AddNew()

Dim drView As DataRowView
drView = saveBindingSource.Current
' Note: commenting out the next lines will throw
' and error when the column is bound to a
' textbox on the form
drView("CustomerUID") = -1
drView("CustomerNumber") = 0
drView("LastOrder") = "01/01/1900"
End If

' bind textboxes on form to datasource
Me.CompanyName1.DataBindings.Add("Text", saveBindingSource, "Company")
Me.ntxtCustomerNumber.DataBindings.Add("Text", saveBindingSource, "CustomerNumber")
Me.cboType.DataBindings.Add("Text", saveBindingSource, "Type")
Me.cboStatus.DataBindings.Add("Text", saveBindingSource, "Status")
Me.txtLastOrder.DataBindings.Add("Text", saveBindingSource, "LastOrder")

' after binding, clear out "temp data" from textboxes
If saveUpdateMode = "add" Then
ntxtCustomerNumber.Text = "" ' this always throws an error!
txtLastOrder.Text = ""
dtxtLastActive.Text = ""
ntxtYTDSales.Text = ""
ntxtPrevYTDSales.Text = ""
End If

Given this code configuration, the error is being thrown when i try to initialize the bound textbox to "". I'm wondering if I should NOT bind the form in the load event on an "add" and wait until the user asks to save the inserted record. The logic would be changed to bind in the load event if it's an "edit" (i.e. to change data or delete a row) and bind only if the user clicks "save" if the form is invoked from an "add new record" call.

I would like to be able to just call .AddNew without having to worry about "intializing" the non-string fields. Any ideas?

 
Try doing the AddNew after you bind the controls, not before:

' bind textboxes on form to datasource
Me.CompanyName1.DataBindings.Add("Text", saveBindingSource, "Company")
Me.ntxtCustomerNumber.DataBindings.Add("Text", saveBindingSource, "CustomerNumber")
Me.cboType.DataBindings.Add("Text", saveBindingSource, "Type")
Me.cboStatus.DataBindings.Add("Text", saveBindingSource, "Status")
Me.txtLastOrder.DataBindings.Add("Text", saveBindingSource, "LastOrder")


If saveUpdateMode = "add" Then
saveBindingSource.AllowNew = True
saveBindingSource.AddNew()
End If

I used to rock and roll every night and party every day. Then it was every other day. Now I'm lucky if I can find 30 minutes a week in which to get funky. - Homer Simpson

Arrrr, mateys! Ye needs ta be preparin' yerselves fer Talk Like a Pirate Day! Ye has a choice: talk like a pira
 
I moved the addnew after the binding code as you suggested but that caused a different problem. The calling form has a datagrid bound to the same bindingsource the detail form uses.

If I call addnew after binding on the detail form, the textboxes display the values of the current row from the grid on the calling page instead of showing empty textboxes. In other words, by moving the addnew after the binding on the detail form, the form is acting as if I had double-clicked on the grid to edit the selected row.

When I saw your suggestion, I had hoped that the addnew would clear the displayed values from the text boxes to prepare for an "add" but this was not what happened.

Any other ideas I might try? This seems like such a basic operation it should be easy. I must be missing something obvious. But what?
 
I think I've solved the problem. I'm writing this to document the solution I found and to ask if anyone has another way of handling the "addnew" process when using a bindingsource.

To make everything work, the following was necessary:
1. pass a bindingsource to a detail form to allow add, change, delete on the underlying datatable
2. call addnew on the bindingsource
3. before binding anything on the form, provide a temporary (and unique) value to the current row's primary key column as follows:

Dim drView As DataRowView
drView = saveBindingSource.Current
drView("CustomerUID") = -1

4a. if editing an existing record, just bind all the form controls to the binding source as follows:

If saveUpdateMode = "edit" Then
Me.ntxtCustomerNumber.DataBindings.Add("Text", saveBindingSource, "CustomerNumber")
Me.txtYTDSales.DataBindings.Add("Text", saveBindingSource, "YTDSales")
End If

4b. if adding a new record, you need to handle null values for non-string columns in the underlying datatable as follows:

If saveUpdateMode = "add" Then
Dim customerNumberBinding As Binding = New Binding("Text", saveBindingSource, "CustomerNumber", True)
customerNumberBinding.NullValue = ""
ntxtCustomerNumber.DataBindings.Add(customerNumberBinding)

Dim YTDSalesBinding As Binding = New Binding("Text", saveBindingSource, "YTDSales", True)
YTDSalesBinding.NullValue = ""
txtYTDSalesBinding.DataBindings.Add (YTDSalesBinding )
End If

It might be easier to just pass all form controls into a procedure that would set the binding.nullvalue to "" instead of having to hardcode the non-string columns but the above code seems to work.

If there's a better way to handle this process, please post it. Thanks for all your help.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top