问题
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.
回答1:
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);
回答2:
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.
回答3:
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
回答4:
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
来源:https://stackoverflow.com/questions/17601725/accessing-textbox-id