Accessing dynamically generated textboxes
-
I have dynamically created textboxes in a loop, and given them names at creation time.
txtProdName.Name = "txtProdName" + i;
pn.Controls.Add(txtProdName);
txtProdDesc.Name = "txtProdDesc" + i;
pn.Controls.Add(txtProdDesc);The above snippet works fine. Controls are created, and removed as needed. Now, I would like to go back and read or write information into these textboxes, but I'm at a lost as to how to address them. I'm trying to do something like:
txtProdName + i.Text = "Blah";
txtProdDesc + i.Text = "Blah2";Now I know the above code won't work, but wondering if there is someway to do something similar? Or am I totally barking up the wrong tree. Thanks in advance. P.S. I haven't found an answer to this anywhere, which leads me to believe I'm at the wrong tree. :-D
-
I have dynamically created textboxes in a loop, and given them names at creation time.
txtProdName.Name = "txtProdName" + i;
pn.Controls.Add(txtProdName);
txtProdDesc.Name = "txtProdDesc" + i;
pn.Controls.Add(txtProdDesc);The above snippet works fine. Controls are created, and removed as needed. Now, I would like to go back and read or write information into these textboxes, but I'm at a lost as to how to address them. I'm trying to do something like:
txtProdName + i.Text = "Blah";
txtProdDesc + i.Text = "Blah2";Now I know the above code won't work, but wondering if there is someway to do something similar? Or am I totally barking up the wrong tree. Thanks in advance. P.S. I haven't found an answer to this anywhere, which leads me to believe I'm at the wrong tree. :-D
There are several ways to do that - but the easiest is probably to use Controls.Find:
TextBox tbProd = (TextBox)pn.Controls.Find("txtProdName" + i, false).FirstOrDefault();
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
-
There are several ways to do that - but the easiest is probably to use Controls.Find:
TextBox tbProd = (TextBox)pn.Controls.Find("txtProdName" + i, false).FirstOrDefault();
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
Ok, so I follow what you did with the code. Having difficulty in taking it to the next step. My thoughts are, I should now be able to:
tbProd.Text = "Blah";
However, I get the following error: 'System.NullReferenceException'in Project.exe ("Object reference not set to an instance of an object.") And to make sure I really do understand what you suggested:
TextBox tbProd = (TextBox)pn.Controls.Find("txtProdName" + i, false).FirstOrDefault();
Creating a new instance of a textbox, called tbProd that is being set to the first control found in the panel, pn with a name of txtProdName + i, and casting that to type textbox. If I truly understand your code, and the error, it would appear that tbProd didn't actually get the copy I thought it did?? I truly want to thank you for your help.
-
I have dynamically created textboxes in a loop, and given them names at creation time.
txtProdName.Name = "txtProdName" + i;
pn.Controls.Add(txtProdName);
txtProdDesc.Name = "txtProdDesc" + i;
pn.Controls.Add(txtProdDesc);The above snippet works fine. Controls are created, and removed as needed. Now, I would like to go back and read or write information into these textboxes, but I'm at a lost as to how to address them. I'm trying to do something like:
txtProdName + i.Text = "Blah";
txtProdDesc + i.Text = "Blah2";Now I know the above code won't work, but wondering if there is someway to do something similar? Or am I totally barking up the wrong tree. Thanks in advance. P.S. I haven't found an answer to this anywhere, which leads me to believe I'm at the wrong tree. :-D
The WinForms ControlCollection does allow you to use a string Key to access members:
pn.Controls["txtProdName3"].Text = "hello";
When you set the 'Name property of a WinForm Control, you have created the Key (why MS documentation calls it a 'Key baffles me). So, that is a way you could access the run-time created TextBoxes without keeping a direct reference to them in some data structure. However, I strongly advise you not to rely on that, and suggest you do something like this:
public List ListOfTextBoxes = new List();
public void createTextBoxes(int howMany)
{
TextBox txtProdName;
TextBox txtProdDesc;for(int i = 0; i < howMany; i++) { txtProdName = new TextBox(); txtProdDesc = new TextBox(); ListOfTextBoxes.Add(txtProdName); // keep a reference ! ListOfTextBoxes.Add(txtProdDesc); txtProdName.Name = "txtProdName " + i; pn.Controls.Add(txtProdName); txtProdDesc.Name = "txtProdDesc " + i; pn.Controls.Add(txtProdDesc); }
}
// sample uses in code:
ListOfTextBoxes[2].Text = "blah";
// or, take advantage of the string Key of a ControlCollection
pn.Controls["txtProdName3"].Text = "hello";
string tbContent1 = ListOfTextBoxes[0].Text;
But, if you are going to use the Index to access the TextBoxes, you can see immediately that you'll have to remember which index to use for TextBoxes that are 'txtProdDesc, and which to use for 'txtProdName. To make the code clearer, I would use two separate Lists. I would also consider using two Dictionaries of Type <string, TextBox> If the two TextBoxes are designed to function as a "pair;" I'd consider another data structure, or consider creating a custom UserControl ... all depends on your Application and its scope, purpose, run-time load, etc.
«I want to stay as close to the edge as I can without going over. Out on the edge you see all kinds of things you can't see from the center» Kurt Vonnegut.
-
Ok, so I follow what you did with the code. Having difficulty in taking it to the next step. My thoughts are, I should now be able to:
tbProd.Text = "Blah";
However, I get the following error: 'System.NullReferenceException'in Project.exe ("Object reference not set to an instance of an object.") And to make sure I really do understand what you suggested:
TextBox tbProd = (TextBox)pn.Controls.Find("txtProdName" + i, false).FirstOrDefault();
Creating a new instance of a textbox, called tbProd that is being set to the first control found in the panel, pn with a name of txtProdName + i, and casting that to type textbox. If I truly understand your code, and the error, it would appear that tbProd didn't actually get the copy I thought it did?? I truly want to thank you for your help.
The FirstOrDefault method returns
null
if the collection of objects returned by Find has no elements: so use the debugger to look at the Panel.Controls collection and see exactly what it contains - I suspect that it doesn't have anything, in which case you need to look at the environment in which you are calling Find. When are you doing it, what else have you done, that kind of thing. We can't do that for you - we don't have access to your code! And BTW:TextBox tbProd = ....
Doesn't create a new instance - it creates a variable that can reference an instance. It's a small but very, very important distinction!
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
-
The WinForms ControlCollection does allow you to use a string Key to access members:
pn.Controls["txtProdName3"].Text = "hello";
When you set the 'Name property of a WinForm Control, you have created the Key (why MS documentation calls it a 'Key baffles me). So, that is a way you could access the run-time created TextBoxes without keeping a direct reference to them in some data structure. However, I strongly advise you not to rely on that, and suggest you do something like this:
public List ListOfTextBoxes = new List();
public void createTextBoxes(int howMany)
{
TextBox txtProdName;
TextBox txtProdDesc;for(int i = 0; i < howMany; i++) { txtProdName = new TextBox(); txtProdDesc = new TextBox(); ListOfTextBoxes.Add(txtProdName); // keep a reference ! ListOfTextBoxes.Add(txtProdDesc); txtProdName.Name = "txtProdName " + i; pn.Controls.Add(txtProdName); txtProdDesc.Name = "txtProdDesc " + i; pn.Controls.Add(txtProdDesc); }
}
// sample uses in code:
ListOfTextBoxes[2].Text = "blah";
// or, take advantage of the string Key of a ControlCollection
pn.Controls["txtProdName3"].Text = "hello";
string tbContent1 = ListOfTextBoxes[0].Text;
But, if you are going to use the Index to access the TextBoxes, you can see immediately that you'll have to remember which index to use for TextBoxes that are 'txtProdDesc, and which to use for 'txtProdName. To make the code clearer, I would use two separate Lists. I would also consider using two Dictionaries of Type <string, TextBox> If the two TextBoxes are designed to function as a "pair;" I'd consider another data structure, or consider creating a custom UserControl ... all depends on your Application and its scope, purpose, run-time load, etc.
«I want to stay as close to the edge as I can without going over. Out on the edge you see all kinds of things you can't see from the center» Kurt Vonnegut.
Gentlemen, I wanted to thank you for your help. Both of you got me going again.