out2havefun


I hope I can explain this clearly.

I have form1 with a data-bound list box containing a list of CustomerNames (Display Member=CustomerName and Value Member=CustomerID). Also on form1 are some labels bound to the same binding source for name, address, city state, etc. When I select different names in the list box, the labels change appropriately. Everything works great.

Now here is the problem. I created form2 which is an edit form with textboxes to change the customer's info. The problem is that when form2 opens, I always see the first customer in the table displayed in the textboxes, regardless of which customer name I had selected from the list box in form1. The list box (form1) should be bound (by CustomerID) to these textboxes on form2 but apparently I am missing something. Can someone help



Re: Windows Forms Data Controls and Databinding Data binding problem between two forms

ARK88

Could you describe the bindings in your application in a little more detail For example, could you post or explain how you have the code (or design-time setup) for binding on Form1 Also, could you post or explain how you have the code (or design-time setup) for binding on Form2 You'll need to make sure Form2 is using an instance of the same binding source as Form1... which means you would more than likely need to pass a reference to the binding source from Form1 to Form2. If you can explain these things a little more I'm sure we'll be able to help you figure this one out.





Re: Windows Forms Data Controls and Databinding Data binding problem between two forms

out2havefun


I’m using design-time setup of the bindings for both forms. The ListBox on form1 is set as follows: Data Source = CustomersBindingSource; Display Member = CustomerName; Value Member = CustomerID. I’ve set the labels on form1 using the Properties window for each label (DataBindings)-Text property to CustomersBindingSource and then to the appropriate field (CustomerName, Address, City, etc.). This form1 works perfectly. The labels display each field properly when the app is run.

<!--[if !supportEmptyParas]--> <!--[endif]-->

Now comes form2. Using the same dataset in the Data Sources window, I set the Details view for the Customers table and drag it to the form. This now gives me a CustomersBindingSource and a CustomersTableAdapter along with several textboxes bound to the same fields as the labels on form1.

<!--[if !supportEmptyParas]--> <!--[endif]-->

If I now run the app, form1 displays and as I select each name in the Listbox, the labels correctly show the data for the selected name. When I click the Edit button (I have an Edit button to call form2), form2 displays, but the textboxes only display data for the first name in the Listbox of form1. It’s like form2 is not connected with the data in the Listbox.

<!--[if !supportEmptyParas]--> <!--[endif]-->

I didn’t understand what you mean by “pass a reference to the binding source from Form1 to Form2”. That may be the problem, but I don’t understand what is needed.

I hope this explanation helps. Thanks for your help.






Re: Windows Forms Data Controls and Databinding Data binding problem between two forms

ARK88

When you dragged the Customers table onto Form2 and Visual Studio created a CustomersBindingSource, that is a different binding source than the one created on Form1. Yes, they have the same name, but they are two independent instances (meaning, they manage their own copies of data, not the same copy of data).

Somewhere within Form1 you probably have code to create and display an instance of Form2... Assuming you do, during the creation of the instance of Form2 you could supply a reference to the binding source on Form1 so that Form2 and Form1 are using the exact same binding source (and therefore the same data). Below is some sample code of conceptually what I'm talking about. I tried to use objects similar to what you talked about so that it is a little more relevant to your application.

Form1 has a listbox and several labels on it. The listbox and the labels are bound to a binding source named "customersBindingSource". When Form1 displays, the listbox is populated with the data in the underlying Customers DataTable, and the labels update with the data from the currently selected item in the listbox. There is also a button on Form1, that when clicked creates an instance of Form2, passing a reference to Form1's "customersBindingSource" to Form2's constructor, then displays Form2. Form2 takes the binding source passed to it's constructor, and binds it to the textboxes that are on it. If you have questions about the code, please ask and I'll try to explain it more/better:

Form1

Code Snippet

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

private void Form1_Load(object sender, EventArgs e)

{

DataSetCustomer.CustomersRow dr;

// Load some data into the Customers DataTable.

for( Int32 i = 1; i < 11; i++ )

{

dr = dataSetCustomer.Customers.NewCustomersRow();

dr.CustomerName = string.Format("Customer - {0}", i);

dr.Address = string.Format("Address - {0}", i);

dr.City = string.Format("City - {0}", i);

dr.State = string.Format("State - {0}", i);

dr.PostalCode = string.Format("PostalCode - {0}", i);

dataSetCustomer.Customers.AddCustomersRow( dr );

};

dataSetCustomer.AcceptChanges();

}

private void button1_Click(object sender, EventArgs e)

{

// Create an instance of Form2. Pass the binding source

// from Form1 so that Form2 displays the information from

// the currently selected item/row on Form1.

Form2 frm = new Form2(customersBindingSource);

frm.ShowDialog();

frm.Dispose();

frm = null;

}

}

Form2

Code Snippet

public partial class Form2 : Form

{

private BindingSource m_bs;

public Form2()

{

InitializeComponent();

}

// An overloaded constructor on Form2 so that

// a binding source could be passed to it.

public Form2(BindingSource bs) : this()

{

// Save a module-level reference to the binding source

// in case you need to refer to it somewhere else within

// Form2's code.

m_bs = bs;

// Setup the databindings on your textboxes. Notice that

// it is bound to the binding source that was passed, so it

// will display the data that was currently selected on Form1.

txtCustomerName.DataBindings.Add("Text", m_bs, "CustomerName");

txtCustomerAddress.DataBindings.Add("Text", m_bs, "Address");

txtCustomerCity.DataBindings.Add("Text", m_bs, "City");

txtCustomerState.DataBindings.Add("Text", m_bs, "State");

txtCustomerPostalCode.DataBindings.Add("Text", m_bs, "PostalCode");

}

}





Re: Windows Forms Data Controls and Databinding Data binding problem between two forms

out2havefun


Thank you very much for the help, ARK88. I think I understand what you are saying, but I definitely do not understand your code. I guess I should have mentioned that I am using VB2005 EE. I think maybe your code looks like C++ Anyway, I do not understand it. You're right. I used the following code to call form2 (named btnEditCustomer):

Private Sub btnEditCustomer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEditCustomer.Click

My.Forms.frmEditCustomer.ShowDialog()

End Sub

I need just a little more help with the code. Thanks.




Re: Windows Forms Data Controls and Databinding Data binding problem between two forms

ARK88

Sorry... you didn't specify which language you program in, so I defaulted to C#... below is basically the same code, but in VB. If you have questions, please don't hesitate to ask.

Form1

Code Snippet

Public Class Form1

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

Dim dr As DataSetCustomer.CustomersRow

Dim i As Int32

' Put some data into the Customers datatable.

For i = 1 To 10

dr = DataSetCustomer.Customers.NewCustomersRow()

dr.CustomerName = String.Format("Customer - {0}", i)

dr.Address = String.Format("Address - {0}", i)

dr.City = String.Format("City - {0}", i)

dr.State = String.Format("State - {0}", i)

dr.PostalCode = String.Format("PostalCode - {0}", i)

DataSetCustomer.Customers.AddCustomersRow(dr)

Next i

DataSetCustomer.AcceptChanges()

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim frm As Form2

' Create new instance of Form2, pass it a reference

' to Form1's binding source so that Form2 shows the

' data of the current item in the binding source.

frm = New Form2(CustomersBindingSource)

frm.ShowDialog()

frm.Dispose()

frm = Nothing

End Sub

End Class

Form2

Code Snippet

Public Class Form2

Private m_bs As BindingSource

Public Sub New(ByVal bs As BindingSource)

Me.InitializeComponent()

' Set a module-level reference to the binding

' source, in case other methods in your Form2

' code need to operate on the binding source.

m_bs = bs

' Setup the databindings for the textboxes on Form2.

txtCustomerName.DataBindings.Add("Text", m_bs, "CustomerName")

txtCustomerAddress.DataBindings.Add("Text", m_bs, "Address")

txtCustomerCity.DataBindings.Add("Text", m_bs, "City")

txtCustomerState.DataBindings.Add("Text", m_bs, "State")

txtCustomerPostalCode.DataBindings.Add("Text", m_bs, "PostalCode")

End Sub

End Class





Re: Windows Forms Data Controls and Databinding Data binding problem between two forms

out2havefun


I'm sorry ARK88, but I really don't understand your code for form1 nor the module-level reference in form2. I tried to copy your code into a new Windows application using a different SQL database with a Customer table and appropriate fields. But I got blue squiggly underlines for every line referencing DataSetCustomer in the form1 code. I added a form2 to the project and got a blue squiggly underline for the reference to CustomersBindingSource (said it was not declared).

I guess I have become so dependent on using as little coding as possible, that I have a real problem writing code. Sorry to be a dummy, but it makes no sense to me. I do appreciate your help though, immensely.




Re: Windows Forms Data Controls and Databinding Data binding problem between two forms

ARK88

Okay... no problem. Let's back up a little then.

Please be a little patient with me as I try to assist you with this, as I am not able to see your code... so I definitely have to "shoot from the hip" a little. It is also important for me to say that the things described below are things I would like you to do to your code... not to the sample code I posted previously. At the same time, I don't want to hose-up anything you already have working, so I ask that you do not delete any of your code, but instead just comment it out.

Here we go...

Somewhere within your Form1 you have code that displays Form2. Whatever code you currently have to display Form2, comment it out. Then, right below the code you comment out, I would like you to add the following code:

Code Snippet

Dim frm2 As Form2 = New Form2()

frm2.ShowDialog(Me)

frm2.Dispose()

frm2 = Nothing

That [above] is the only change I want you to make to your Form1.

Now on to Form2...

I don't know what your Form2 looks like, nor do I know what text fields you have on it... so I can't get real specific with my instructions, so please keep that in mind in this next section.

Bring up your Form2's interface and undo the databindings for two of the textboxes that are on it that you currently have bound to Form2's binding source. I don't know exactly how you originally bound them, but I believe the way I'd like you to unbind them is to click on the appropriate field on your form, then go to the Properties window, expand the "(DataBindings)" property, then set the "Text" item to "None". Do that for two of your bound textboxes.

If your Form2 does not have a "Load" event, then I'd like you to create one. The simplest way to do that is to double-click on Form2 (in design mode). Inside the Form2 "Load" event, I'd like you to add the following code (preferrably as the first couple of lines within that event):

Code Snippet

Dim bs As BindingSource = CType(Me.Owner, Form1).CustomersBindingSource

[TextBox 1].DataBindings.Add("Text", bs, "[ColumnName 1]")

[TextBox 2].DataBindings.Add("Text", bs, "[ColumnName 2]")

Now... what I need you to do with the code above, is to modify the yellow-highlighted items with the names of the textboxes you unbound per the instructions I gave you a couple paragraphs ago. For the blue-highlighted items, you'll need to change these to be the column names in the underlying data you are binding to these fields.

After having made the changes described above, you should be all set to test. Run your application, select an item in Form1's listbox, then click your edit button to display Form2. If we did this all correctly, the two textboxes you modified on Form2 should be showing the data related to the item selected in the listbox on Form1. All the other fields on Form2 should not be showing data related to the item you selected in the listbox on Form1 (unless of course you have the first item in the listbox selected).

I'm going to leave it at that for right now, and wait for you to get back to me letting me know if this worked or not. If it doesn't, then I may need you to start posting some of your code so that I can see how you have your application structured.

Talk to you later...





Re: Windows Forms Data Controls and Databinding Data binding problem between two forms

Yu Guo – MSFT

Hi, out2havefun,

Based on my understanding, you want to be able to get the same record in the newly opened form, don't you

I think ARK88's codes should be great, and I will try to make them clear.

There is a object call CurrencyManager which sync the controls which bind to the same DataSource.

http://msdn2.microsoft.com/en-us/library/system.windows.forms.currencymanager(vs.80).aspx

That's why your Form1 works perfect with the ComboBox and TextBoxes.

But in your Form2, you get another DataSource which always gives you first record, because it has the different CurrencyManager with Form1.

So, the solution is to send the same BindingSource to Form2 through Constructor

I guess you are using Drag-n-Drop to bind the data to controls.

Let's say there you have a Table1BindingSource.

In your button's click event

Code Snippet

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim form As Form2 = New Form2(Me.Table1BindingSource) //Change this to your BindingSource Name

form.Show()

End Sub

Then you should add a empty BindingSource (BindingSource1) to Form2 and write a Constructor for Form2

Code Snippet

Public Sub New(ByVal bindingsource As BindingSource)

Me.InitializeComponent()

Me.BindingSource1 = bindingsource

Me.TextBox1.DataBindings.Add("Text", bindingsource, "Name") //Add your own Control's Data Binding

//...... //Add your own Control's Data Binding

Me.TextBox2.DataBindings.Add("Text", bindingsource, "Id") //Add your own Control's Data Binding

End Sub

How to add DataBinding:

http://msdn2.microsoft.com/en-us/library/system.windows.forms.control.databindings(VS.80).aspx

And you may add a button to save the state, add the following codes into the click event

Code Snippet

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

DirectCast(Me.BindingSource1.DataSource, DataSet).AcceptChanges()

End Sub

You will find that the Data in Form1 is changed.

Hope this helps,

Regards






Re: Windows Forms Data Controls and Databinding Data binding problem between two forms

out2havefun


You guys are awesome !! Thanks to you both. ARK88 it worked exactly as you said. I really appreciate your breaking it down for me to understand. I also tried the changes as suggested by Yu Guo which worked fine as well. I'm going to read more about the CurrencyManager Class. I searched a ton through many books and via Google and could not find the answer until you guys helped me. You're Great !




Re: Windows Forms Data Controls and Databinding Data binding problem between two forms

out2havefun


I have one last question about your last code snippet.
The last code snippet in your answer was DirectCast(Me.BindingSource1.DataSource, DataSet).AcceptChanges()
Even though I didn't really understand it, it worked perfectly and as you said, it changed my data in form1. However, I can't seem to get these changes to save to my database. I added the following code to the click event of my btnEditCustomer on form1 (this code executes after form2 closes and form1 shows the changes):

Me.CustomersBindingSource.EndEdit()
Me.CustomersTableAdapter.Update(Me.PTCDataSet.Customers)

But it doesn't save to the database. When I close and reopen the app, the changes are not there. Can you help me understand this Thanks.





Re: Windows Forms Data Controls and Databinding Data binding problem between two forms

Yu Guo – MSFT

Hi, out2havefun,

For your first question, the AcceptChanges() is used to notify the binded TextBox that the datasource has been changed. In fact, it will tell that DataViews have all been changed and DataViews will notify the binded Controls.

http://msdn2.microsoft.com/en-us/library/system.data.dataset.acceptchanges.aspx

And if you want to update the DataBase, you cannot do that after AcceptChanges(), because if you update after AcceptChanges, the DataAdapter will consider the Data not changed.

Let's do a little modification here.

First, in the codes to open Form2

Code Snippet

Dim form As Form2 = New Form2(Me.Table1BindingSource)

form.Owner = Me 'This sentence is used to define the Owner of Form2

form.Show()

Second in Form 2, in the codes to update

Code Snippet

'DirectCast(Me.BindingSource1.DataSource, DataSet).AcceptChanges() 'Comment this line, you don't need to use AcceptChanges to notify the controls in Form1 anymore.

DirectCast(Me.Owner, Form1).Table1BindingSource.EndEdit()

DirectCast(Me.Owner, Form1).Table1TableAdapter.Update(DirectCast(Me.Owner, Form1).NewDataSet.Table1) ''These two lines are used to update data in DataBase

However, if you are using Access DB, everytime you rebuild the project, a new Access File will be copied into the debug folder, and it seems that your update is failed, but in fact, the old file has already been changed.

And the key field in your table is not supported for updating unless you rewrite your update command

Hope this helps,

Regards






Re: Windows Forms Data Controls and Databinding Data binding problem between two forms

out2havefun


Excellent ! It works perfectly. Thanks very much for all your help Yu Guo and thanks also to ARK88. You guys are awesome!

out2havefun




Re: Windows Forms Data Controls and Databinding Data binding problem between two forms

chadbengen

I have been struggling with this for some time and was very happy to run across all these very clear walk throughs. Using the above samples I've been able to successfully share the same bindingsource on my Form2. However, I want to use a combobox for some of my data entry on Form2 and I'm struggling with how to do it.

One of the details I want to display is the gender. In the dataset used by Form1 I have a table titled SEX. The value in this table is either "F", "M", or "N" ("Female", "Male", "NA"). This is the code I've come up with so far:

'bs is the bindingsource from the detail form, Form1

'SEXtableadapter is filled on the form_Load event in Form2

Me.cbGender.DataSource = Me.SEXBindingSource

Me.cbGender.DisplayMember = "DESCRIPTION"

Me.cbGender.ValueMember = "CODE"

cbGender.DataBindings.Add("Text", bs, "SEX")

When I navigate the dgv in Form1, cbGender is correctly displaying the value, and when I click the drop button it shows the descriptions correctly. It should be displaying the description as the user navigates Form1.

How do I do this correctly





Re: Windows Forms Data Controls and Databinding Data binding problem between two forms

ARK88

Try using the "SelectedValue" property instead of "Text":

Code Snippet

cbGender.DataBindings.Add("SelectedValue", bs, "SEX");