Hi,
I am writing this, because after searching on web also, I did not found a proper solution. I am not sure if this behavior is a known issue and if there is any right workaround.
Problem: I have a TabPageControl with 2 tab pages.Tab2 has textbox3 with bindingset to a BindingSource1. I would like to initialize textbox with default values when ever BindingSource1.AddNew() method is called. Button1 is outside TabPage on a Form.
For this following code is written but....Textbox does not get initialize until I have activated or switch to TabPage2 atleast once.
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click BindingSource1.AddNew() TextBox3.Text = "VS.NET2008" End Sub
A Temp Solutionis toactivate TabPage2and then go back to TabPage1, like below.
TabControl1.SelectTab(TabPage2) TabControl1.SelectTab(TabPage1)
Above is not a perfect or a professional solution as it does gives a flicker effect at runtime and also it takes around 1 to 2 seconds to initialize all controls on TabPage2 and then switch back to TabPage1.
Digging a deep more I found that controls are not created,I found this with help of following code
Me.TextBox3.Created.ToString().
This returns false until tabPage2 is activated atleast one.
Question:
1. So is there a solution to this problem. 2. Is there a way to force create controls on TabPage2 when controls are bind to BindingSource1
| | Jignesh Desai Thursday, February 05, 2009 9:35 AM | Hi Jignesh,
Thank you for your reply!
> I would like to initialize controls with default values and because of this odd behaviour it causes troubles.
If you're using DataSet/DataTable as the underlying data source, I recommend you to set the default value of the column in the DataTable rather than set the Text property of the bound TextBox directly.
To do this, open the DataSet in the designer and selec the DataTable in question. Set the DefaultValue property of the columns you want in the DataTable in Properties window.
If you're using list that contains instances of custom type as the underlying data source, handle the AddingNew event of the BindingSource component to set the default value. For example:
public class Person { private string name; public string Name { get { return name; } set { name = value; } } } BindingSource bs = new BindingSource();
private void Form1_Load(object sender, EventArgs e) { List<Person> list = new List<Person>(); bs.DataSource = list; bs.AddingNew += new AddingNewEventHandler(bs_AddingNew); this.textBox1.DataBindings.Add("Text", bs, "Name"); }
void bs_AddingNew(object sender, AddingNewEventArgs e) { Person obj = new Person(); obj.Name = "new name"; e.NewObject = obj; } > I have some similar issue with DataGridView Control, if you know solution for this second issue, let me know.
As franking has suggested, you can subscribe the DefaultValueNeeded event of the DataGridView and in the event handler check the first item in the DataGridViewComboBoxColumn's DataSource and set that value as the default value of the cell.
Hope this helps. If you have any question, please feel freeto let me know.
Sincerely, Linda Liu
- Marked As Answer byLinda LiuMSFT, ModeratorThursday, February 12, 2009 2:41 AM
-
| | Linda Liu Wednesday, February 11, 2009 8:56 AM | Hi Jignesh,
I performed a test based on your description and did reproduce the problem on my side.
When a control is newed, it is not created at this time. Only after this control is added to a form or a container AND this container is visible, this control will be created. In your scenario, since the controls are added to the second TabPage which is not visible when the form is loaded, these controls will not be created until the second TabPage is made visible.
I have tried set the Visible property of the TextBox which is added to the second TabPage to true in the form's Load event handler, but without success. The TextBox's Visible property remains false until the second TabPage is visible.
So this behavior is by design and there doesn't seem to be a workaround.
Anyway, I don't think this behavior would cause any problem.
If you have any concern, please feel free to let me know.
Sincerely, Linda Liu | | Linda Liu Monday, February 09, 2009 10:34 AM | HiLinda Liu, This behaviour is ofcouse of concern for me asafter i call BindingSource1.AddNew() method , I would like to initialize controls with default values and because of this odd behaviour it causes troubles.
There should be some way to force create controls afterBindingSource1.AddNew() .
Anyways ...
I have some similar issue with DataGridView Control, if you know solution for this second issue, let me know. Issue is posted here on this thread http://social.msdn.microsoft.com/Forums/en-US/winformsdatacontrols/thread/c7501286-da89-4fef-8ab1-2f61641b9a5f
Regards JIGNESH | | Jignesh Desai Monday, February 09, 2009 10:44 AM | Hi Jignesh,
Thank you for your reply!
> I would like to initialize controls with default values and because of this odd behaviour it causes troubles.
If you're using DataSet/DataTable as the underlying data source, I recommend you to set the default value of the column in the DataTable rather than set the Text property of the bound TextBox directly.
To do this, open the DataSet in the designer and selec the DataTable in question. Set the DefaultValue property of the columns you want in the DataTable in Properties window.
If you're using list that contains instances of custom type as the underlying data source, handle the AddingNew event of the BindingSource component to set the default value. For example:
public class Person { private string name; public string Name { get { return name; } set { name = value; } } } BindingSource bs = new BindingSource();
private void Form1_Load(object sender, EventArgs e) { List<Person> list = new List<Person>(); bs.DataSource = list; bs.AddingNew += new AddingNewEventHandler(bs_AddingNew); this.textBox1.DataBindings.Add("Text", bs, "Name"); }
void bs_AddingNew(object sender, AddingNewEventArgs e) { Person obj = new Person(); obj.Name = "new name"; e.NewObject = obj; } > I have some similar issue with DataGridView Control, if you know solution for this second issue, let me know.
As franking has suggested, you can subscribe the DefaultValueNeeded event of the DataGridView and in the event handler check the first item in the DataGridViewComboBoxColumn's DataSource and set that value as the default value of the cell.
Hope this helps. If you have any question, please feel freeto let me know.
Sincerely, Linda Liu
- Marked As Answer byLinda LiuMSFT, ModeratorThursday, February 12, 2009 2:41 AM
-
| | Linda Liu Wednesday, February 11, 2009 8:56 AM | HiLinda Liu
Your Suggestion Works!
Thanks JIGNESH | | Jignesh Desai Saturday, February 14, 2009 10:22 AM | I had to tackle this same problem, and iterating though the tabpages was clunky and seizure-causing :) Here was what I came up with for controls on other tabpages that have yet to be created: The BindingComplete event for the binding source will fire for each databound control (even ones not created yet), so this was the logical place to start. Private Sub YourBindingSource_BindingComplete(ByVal sender As Object, ByVal e As System.Windows.Forms.BindingCompleteEventArgs) _ Handles YourBindingSource.BindingComplete If Not e.Binding.Control.Created Then 'if a control is residing on a different tabpage and the tabpage has not yet been selected, the child controls will not be created, hence this test 'make sure the control's parent is a tabpage If e.Binding.Control.Parent.GetType.Name.ToLower = "tabpage" Then 'show the tabpage - note the tabControl selectedIndex remains the same e.Binding.Control.Parent.Show() 'The child controls on the tab page will now be created and filled with data! End If End If End Sub I only tested it for TextBoxes and ComboBoxes. This could use some modifications for other types of container controls... anyone care to make this more generalized? - Proposed As Answer byDaven9000 Saturday, August 08, 2009 10:27 PM
-
| | Daven9000 Saturday, August 08, 2009 10:27 PM |
|