.NET Forum / Windows Forms / WinForm Data Binding / April 2007
Databinding with own BindingContext for control does not work
|
|
Thread rating:  |
Rolf Welskes - 11 Apr 2007 16:12 GMT Hello, the problem I have is as follows: I have a control MyPanel : Panel ....... In the constructor I have: pubic MyPanel() { InitializeComponents(); this.BindingContext = new BindingContext(); }
Now in a form drag one or more MyPanel objects in the form. In a panel in this form drag a DataGridView and a TextBox. Now bind the datagrid to a DataSet, Table01. Now bind the textbox to the same DataSet, Table01.Name for example.
If you now start the program, the data in the datagrid are there. But the textbox has not the data (Name) of the line in the data.
I construct this to have independent Views of the same datasource. If you bind for example a listbox in the same way as the textbox, all works fine, but not the textbox.
Remark: I do not want in this situation use BindingSource, maybe this works.
Seems with this binding situatuation, the textbox binds to another datasource then the datagrid.
Thank you for any help.
Rolf Welskes
Linda Liu [MSFT] - 12 Apr 2007 05:47 GMT Hi Rolf,
I performed a test based on your description but didn't reproduce the problem on my side.
The following is the walkthrough of my test.
1. Create a WinFoms application, add a DataSet called 'DataSet1' into the project. Add a DataTable called 'DataTable1' and add two data columns called 'Column1' and 'Column2' into DataTable1.
2. Add a derived Panel class into the project. The following is the code of the derived Panel: class MyPanel:Panel { public MyPanel() { this.BindingContext = new BindingContext(); } }
3. Build the project and add an instance of the MyPanel onto a form. Add a DataGridView and a TextBox into the MyPanel control. Add a Button and an instance of DataSet1 to the form.
4. Add the following code to add some data into the data source and bind the DataGridView and TextBox to the data source:
private void Form1_Load(object sender, EventArgs e) { DataRow row = this.dataSet11.DataTable1.NewRow(); row[0] = "11"; row[1] = "aa"; this.dataSet11.DataTable1.Rows.Add(row);
row = this.dataSet11.DataTable1.NewRow(); row[0] = "22"; row[1] = "bb"; this.dataSet11.DataTable1.Rows.Add(row);
this.textBox1.DataBindings.Add("Text", this.dataSet11, "DataTable1.Column1"); this.dataGridView1.DataSource = this.dataSet11; this.dataGridView1.DataMember = "DataTable1"; }
5. In the Button's Click event handler, add the following code:
private void button1_Click(object sender, EventArgs e) { this.myPanel1.BindingContext[this.dataSet11, "DataTable1"].Position++; }
6. Build the run the application. Both the TextBox and DataGridView display data in the data source. When I click the button on the form, both the TextBox and DataGridView navigate to the next row in the DataTable1.
In my test project, the TextBox and DataGridView are bound to the same data source and use the same BindingManagerBase.
If I move DataGridView from the MyPanel control to the form, the DataGridView is still bound to the same data source, but uses a different BindingManagerBase from the TextBox does at this time, because the BindingContext associated with the MyPanel control is different from that of the form. At this time, we should use the following code to navigate the data for the DataGridView:
this.BindingContext[this.dataSet11, "DataTable1"].Position++;
In fact, no matter what BindingManagerBase the TextBox uses, once it is bound to a data source and the data source has data in it, the TextBox should display data in data source.
You may have a try commenting out the line of code 'this.BindingContext = new BindingContext();' from the constructor of the MyPanle class, to see if the TextBox could show the data in the data source when the application starts up.
If the problem is still not resolved, you may send me a sample project that could just reproduce the problem. To get my actual email address, remove 'online' from my displayed email address.
Sincerely, Linda Liu Microsoft Online Community Support
================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights.
Relaxin - 12 Apr 2007 11:21 GMT That's a great example Linda, but now I have a question.
I have create some custom business objects that support most of the need functionality you would expect.
The thing that is missing is the ability for my Collection class to be notified when a different record has been selected within the grid.
My question is, how can a business object gain access to the BindingContext so that the business object is notified when the selection has changed?
Thanks
> Hi Rolf, > [quoted text clipped - 109 lines] > This posting is provided "AS IS" with no warranties, and confers no > rights. Linda Liu [MSFT] - 16 Apr 2007 11:57 GMT Hi Relaxin,
> how can a business object gain access to the BindingContext so that the business object is notified when the selection has changed?
I don't think a business object could gain access to the BindingContext, because we could only gain access to the BindingContext through the corresponding control (the derived Panel control, in this case).
To get notified when the current item in a data source is changed, we could subscribe the PositionChanged event of the CurrencyManager object associated with the data source. The following is a sample.
// myPanel1 is the derived Panel control CurrencyManager cm = this.myPanel1.BindingContext[this.dataSet11, "DataTable1"] as CurrencyManager; cm.PositionChanged += new EventHandler(cm_PositionChanged);
void cm_PositionChanged(object sender, EventArgs e) { MessageBox.Show("position changed"); }
Hope this helps.
Sincerely, Linda Liu Microsoft Online Community Support
Relaxin - 16 Apr 2007 18:05 GMT > Hi Relaxin, > [quoted text clipped - 14 lines] > "DataTable1"] as CurrencyManager; > cm.PositionChanged += new EventHandler(cm_PositionChanged); A business object can't do this automatically.
Rolf Welskes - 13 Apr 2007 16:06 GMT Hello, thank you, I think I found the reason for the problem.
You do it in code.
If you do all in designer then your code construtions espespially this.textBox1.DataBindings.Add("Text", this.dataSet11, "DataTable1.Column1"); the designer lays in the constructor and not in OnLoad.
if I move this line from constructor to Onload it works.
But It should work with the designer. The line: this.BindingContext = new BindingContext(); in the MyPanel-Konstruktor is no problem, because it it called in the constructor of the form before datebindinig-code.
So why does this not work? If you have it in the form not in the Panel with the own BindingContext it works with desiger. If you have it in the panel with own Binding Context and bind in desiger DataGridView, ListBox means list-based objekts it works, but only simple DataBinding by designer does not work. Seems because it is in Constructor not in OnLoad.
Thank you and best regards Rolf Welskes
Linda Liu [MSFT] - 16 Apr 2007 11:37 GMT Hi Rolf,
Thank you for your reply.
I performed another test and did reproduce the problem on my side. Instead of binding the TextBox to the data source in the form's Load event handler, I bind it at design time. When the program is run, the TextBox shows an empty text in it.
If I remove the code 'this.BindingContext = new BindingContext();' from the derived Panel's constructor, the problem doesn't exist.
I check the IsBinding property's value of the Binding instance as follows: bool result = this.textBox1.DataBindings["Text"].IsBinding; and the value returns 'false'. This is why the TextBox doesn't show the data in the data source.
In fact, if the control is not visible, it won't be created. If a control is bound to a data source when it has not been created, the Binding instance added to the DataBindings collection of the control is not active.
As we all know, when we bind the TextBox at design time, the code of data binding is serialized in the InitializeComponent method of the form, which means that the TextBox is bound to the data source when it is not visible, i.e. not created, while the application is run.
If the BindingContext object of the derived Panel control is equal to the form's, the Binding instance of the TextBox will be acivated when the TextBox becomes visible. However, if the BindingContext object of the derived Panel control is different from that of the form, the above Binding instance won't be activated even after the TextBox becomes visible.
To avoid this, we could bind the TextBox to the data source AFTER the TextBox becomes visible, e.g do the data binding in the form's Load event handler.
Hope I make some clarifications.
If you have any question, please feel free to let me know.
Sincerely, Linda Liu Microsoft Online Community Support
Rolf Welskes - 17 Apr 2007 15:30 GMT Hello, thank you for your informations. I have understand this and so I will bind the simple controls in code. Thank you again and best regards Rolf Welskes
> Hi Rolf, > [quoted text clipped - 43 lines] > Linda Liu > Microsoft Online Community Support
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|