vadim
vadim

Reputation: 211

Accessing TextBox ID

I have a method that creates Textboxes each time the button is clicked. However I am trying to access the Textbox ID in another method. Something seems to be out of scope, here is the code:

    public partial class _Default : System.Web.UI.Page
{
    TextBox box = new TextBox();

    protected void Page_Load(object sender, EventArgs e)
    {



    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        ViewState["count"] = Convert.ToInt32(ViewState["count"]) + 1;
        Label1.Text = ViewState["count"].ToString();
        int test = int.Parse(string.Format("{0}", ViewState["count"]));

            for (int j = 0; j < test; j++)
            {

                TableRow r = new TableRow();

                box.ID = "Textbox" + j;

                TableCell c = new TableCell();
                c.Controls.Add(box);
                r.Cells.Add(c);
                table1.Rows.Add(r);
                Response.Write(box.ID);

            }

            if (test == 4)
            {
                Button1.Visible = false;
            }

    }

    protected void Button2_Click(object sender, EventArgs e)
    {

        Response.Write(box.ID);
    }

I would like to Button2_Click to print out the box.ID to make sure it's able to access it.

Upvotes: 0

Views: 6232

Answers (4)

Igor
Igor

Reputation: 15893

To always create as many text boxes as the number of times user clicked Button1, in your Page_Load you have to run code:

int test = 0;
if (ViewState["count"] != null)
   test = (int)ViewState["count"];

for (int j = 0; j < test; j++)
{
    TextBox box = new TextBox();
    box.ID = "Textbox" + j;
    textBoxes.Add(box.ID, box);
    TableRow r = new TableRow();
    TableCell c = new TableCell();
    c.Controls.Add(box);
    r.Cells.Add(c);
    table1.Rows.Add(r);
}

where textBoxes is a Page class member:

Dictionary<string, TextBox> textBoxes = new Dictionary<string, TextBox>();

Then, in Button2_Click:

string ids = "";
foreach(string id in textBoxes.Keys)
{
    ids = ids + id + ",";
}
Response.Write(ids);

Upvotes: 2

Win
Win

Reputation: 62260

The key is you need to reload the dynmaically created controls on post back.

Otherwise, they will become null, and you cannot access the values.

Note: you do not need to use Response.Write.

Here is the example.

<asp:Label runat="server" ID="Label1"></asp:Label>
<asp:Table runat="server" ID="table1"></asp:Table>
<asp:Button runat="server" ID="Button1" OnClick="Button1_Click" 
   Text="Create TextBoxes" />
<asp:Button runat="server" ID="Button2" OnClick="Button2_Click" 
  Text="Submit" />

protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack)
    {
        // Reload those control back. It can be in either init or load event.
        int total = Count;
        Label1.Text = total.ToString();

        for (int i = 0; i < total; i++)
            CreateTextBoxes(i);

        Count = total;
    }
}

protected void Button1_Click(object sender, EventArgs e)
{
    Count = Count++;
    CreateTextBoxes(Count);

    if (Count == 4)
    {
        Button1.Visible = false;
    }
}

protected void Button2_Click(object sender, EventArgs e)
{
    var results = new List<string>();
    foreach (TableRow row in table1.Rows)
    {
        foreach (TableCell cell in row.Cells)
        {
            var textBox = cell.Controls[0] as TextBox;
            if (textBox != null)
            {
                results.Add(textBox.Text);
            }
        }
    }
    Label1.Text += string.Join(",", results);
}

private int Count
{
    get { return Convert.ToInt32(ViewState["count"] ?? "0"); }
    set { ViewState["count"] = value; }
}

private void CreateTextBox(int j)
{
    var box = new TextBox();
    box.ID = "Textbox" + j;
    box.Text = "Textbox" + j;

    var c = new TableCell();
    c.Controls.Add(box);

    var r = new TableRow();
    r.Cells.Add(c);

    table1.Rows.Add(r);
}

Output

enter image description here

Upvotes: 2

Tim
Tim

Reputation: 15237

With the way asp.net works, you're recreating box on each postback (both when you click Button1 and when you click Button2). So When you click Button2, even though you've run the code behind for Button1, you're getting a brand new box.

In Button2, you need to do something to access the textbox from the page itself where you added it. I'm not positive how to work with what you're doing but something like

var mytextBox = table1.Rows[x].Cells[y].Controls[z] as TextBox; // PSEUDOCODE

Upvotes: 0

Cortright
Cortright

Reputation: 1174

Your Button1_Click and Button2_Click events would be on two separate postbacks. Box would not have any values assigned to it beyond whatever gets set in the default constructor in this scenario.

Edit: Because you're losing the state of all your code-behind objects and values on postbacks.

Upvotes: 3

Related Questions