The big picture:
0. you are assigning a string to a property 'ID of TextBox in your code: the WinForms TextBox does not have an 'ID property, so this code will not compile in WinForms: are you using some other TextBox that has an 'ID property ?
1. if you are going to have a real-world situation where you have many rows in your Data Object, each populated with 10 TextBoxes, you are going to have, imho, a potentially sluggish application. Is there another strategy for you to allow the user to enter/edit text in your Data Object's cells/fields ... other than putting a WinForm Control in the cell ?
Examining your code what is going on appears to be rather simple:
0. You are creating controls at run-time, rather than design-time.
1. obviously you have a DataObject, perhaps a DataGridView control, or whatever, named 'Table1
2. when you click 'Button1: you execute a loop in which you create 10 new Rows to add to your data object.
3. For each new Row you create two TextBoxes, one named 'tt, and one named 'tx. Those are inserted in Cells, and the Cells inserted in the Row being constructed.
Because the TextBoxes you create are in the scope of the code for Button1's Click event, you can't access them outside that code.
Yes, you might well be able to
dynamically inspect the Rows of your DataObject, query each cell in the row to see if it has a Control, make sure the Control is a TextBox, get the Control, cast it into a TextBox, get its TextBox.Text value, and store that value in a Data Object.
But you can see how much 'work' that would be.
I believe you need to implement a strategy for saving a reference to the run-time created TextBoxes in a way that you can easily access them later, and read their .Text content value and save that in a database.
So, please think about something like:
edit #1 ... cleaned up formatting errors introduced by CP's code-block parser ... edit #1 /
List<TextBox>ListOTT = new List<TextBox>();
List<TextBox>ListOTX = new List<TextBox>();
List<List<TextBox>> RowList = new List<List<TextBox>>();
List<List<List<TextBox>>> RowsList = new List<List<List<TextBox>>>();
So, in your Button Click event:
for (int i = 0; i < 10; i++)
{
ListOTT.Clear();
ListOTX.Clear();
RowList.Clear();
row = new TableRow();
cell = new TableCell();
ttt = new TextBox();
ttt.ID = "t" + i.ToString();
ListOTT.Add(ttt);
cell = new TableCell();
cell.Controls.Add(ttt);
row.Cells.Add(cell);
tx = new TextBox();
tx.ID="tt"+ i.ToString();
ListOTX.Add(ttt);
cell = new TableCell();
cell.Controls.Add(tx);
row.Cells.Add(cell);
RowList.Add(ListOTT);
RowList.Add(ListOTX);
RowsList.Add(RowList);
Table1.Rows.Add(row);
}</row></textbox>
edit #2 If you see <row><textbox> just after the final curly brace above, please ignore: it's an artifact of CP's code-block parser I can't find a way to work around. edit #2 /
Now that suggestion ... a "matryoshka" Russian-nested-doll solution :) ... is only one of many ways you could implement some 'container' or data-structure strategy for storing the TextBoxes you create at run-time. Perhaps using a special Class would be better.
good luck, Bill