Looking at your code, I see you do not keep a reference to the Textbox Controls you create at run-time. The moment the button1_Click code exits there is no variable 'tb.
So, if you wnat to read the Text in one of these created TextBoxes, you are going to have to find it, but, you haven't even given the TextBoxes a distinct identifying 'Name value: how will you find it if the Form has lots of other Controls on it ?
This is almost always a mistake, because you are going to want to ... in any real application ... at some point use run-time created Controls ... in the case of TextBoxes: read their Text content, set their Text content. And, you will probably want to attach some events to those run-time created Controls.
There are a variety of ways you could keep track of the TextBoxes; here's one idea:
a. create a new WinForm project: 'TestRunTimeControlCreation
b. put two Buttons on Form1: 'button1, 'button2
c. add a second Form to the project: 'Form2
d. replace the auto-generated code for Form1 with this:
#region Region:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
#endregion
namespace TestRunTimeControlCreation
public partial class Form1 : Form
{
private const string TextBoxNamePrefix = "tbx_";
private readonly Dictionary<string, TextBox> _dctForm1NameToTBox = new Dictionary<string, TextBox>();
private readonly Dictionary<string, TextBox> _dctForm2NameToTBox = new Dictionary<string, TextBox>();
private readonly Form2 _form2Instance;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
_form2Instance = new Form2();
_form2Instance.Show();
}
private void button1_Click(object sender, EventArgs e)
{
AddTextBoxToForm(this, 5);
}
private void button2_Click(object sender, EventArgs e)
{
AddTextBoxToForm(_form2Instance, 5);
}
public void AddTextBoxToForm(Form targetform, int nTextBox)
{
if (targetform == null || nTextBox < 1)
{
throw new ArgumentException("error in AddTextBoxToForm");
}
string namebase = string.Format("{0}{1}", targetform.Name, TextBoxNamePrefix);
int tBxCnt;
for (var x = 0; x < nTextBox; x++)
{
var newTextBox = new TextBox();
newTextBox.Size = new Size(100,25);
targetform.Controls.Add(newTextBox);
if (targetform is Form1)
{
tBxCnt = _dctForm1NameToTBox.Count;
newTextBox.Name = string.Format("{0}{1}", namebase, tBxCnt);
_dctForm1NameToTBox.Add(newTextBox.Name, newTextBox);
newTextBox.Location = new Point(30, tBxCnt*40 + 60);
}
else if (targetform is Form2)
{
tBxCnt = _dctForm2NameToTBox.Count;
newTextBox.Name = string.Format("{0}{1}", namebase, tBxCnt);
_dctForm2NameToTBox.Add(newTextBox.Name, newTextBox);
newTextBox.Location = new Point(30, tBxCnt*40 + 30);
}
else
{
throw new ArgumentException(string.Format("invalid Form parameter{0}", targetform.Name));
}
newTextBox.Enter += OnTextBoxEnter;
newTextBox.Leave += OnTextBoxLeave;
newTextBox.Text = newTextBox.Name;
}
}
private void OnTextBoxLeave(object sender, EventArgs eventArgs)
{
TextBox tBox = sender as TextBox;
Console.WriteLine("Leave TextBox: {0} TextBox: {1} text: {2}", tBox.TopLevelControl.Name, tBox.Name, tBox.Text);
}
private void OnTextBoxEnter(object sender, EventArgs eventArgs)
{
TextBox tBox = sender as TextBox;
Console.WriteLine("Enter TextBox: {0} TextBox: {1} text: {2}", tBox.TopLevelControl.Name, tBox.Name, tBox.Text);
}
}
}
Hook-up the EventHandlers for the two Buttons on Form1 to the 'button1 and 'button2 ClickHandlers.
Run the project. Click the Buttons, click in a few TextBoxes on Form1, click in a few TextBoxes on Form2. Then: examine what has been written to the Console (in the Visual Studio 'Output window).
Once you have created this kind of Dictionary structure to map the 'Name properties you have assigned to the run-time created TextBoxes, you can access any TextBox using the string 'Name key:
TextBox getATbx;
if(_dctForm1NameToTBox.TryGetValue("Form1_Tbx_2", out getATbx))
{
}