【问题标题】:How to access dynamically created server controls in asp.net如何在 asp.net 中访问动态创建的服务器控件
【发布时间】:2013-10-28 10:59:24
【问题描述】:

我创建了一个网页,我曾经将服务器端控件动态添加到表格中。

我分别为他们分配了 id 的.. 但我无法访问这些动态创建的服务器控件。

C#代码:

 protected void Page_Load(object sender, EventArgs e)
    {
        if (IsPostBack)
        {
            int num_row = (int)Session["No_of_Rows"];
            for (int i = 2; i < num_row; i++)
            {
                TableRow row = new TableRow();
                TableCell cell1 = new TableCell();
                TableCell cell2 = new TableCell();
                TextBox tb = new TextBox();
                CheckBox cb = new CheckBox();

                row.ID = "rw" + i;

                cell1.ID = "c" + i + "1";
                cell2.ID = "c" + i + "2";

                tb.ID = "txt" + i;
                tb.EnableViewState = true;
                cb.ID = "chk" + i;

                cell1.Controls.Add(cb);
                cell2.Controls.Add(tb);

                row.Cells.Add(cell1);
                row.Cells.Add(cell2);

                tbl.Rows.Add(row);
            }
        }
        else
        {
            Session["No_of_Rows"] = 2;
        }




    }
    protected void addRow(object sender, EventArgs e)
    {

        int num_row = (int)Session["No_of_Rows"] + 1;
        TableRow row = new TableRow();
        TableCell cell1 = new TableCell();
        TableCell cell2 = new TableCell();
        TextBox tb = new TextBox();
        CheckBox cb = new CheckBox();

        row.ID = "rw" + num_row;

        cell1.ID = "c" + num_row + "1";
        cell2.ID = "c" + num_row + "2";

        tb.ID = "txt" + num_row;
        //tb.EnableViewState = true;
        cb.ID = "chk" + num_row;

        cell1.Controls.Add(cb);
        cell2.Controls.Add(tb);

        row.Cells.Add(cell1);
        row.Cells.Add(cell2);

        tbl.Rows.Add(row);
        Session["No_of_Rows"] = tbl.Rows.Count;



    }

    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        TextBox tb = new TextBox();

        int num_row = Convert.ToInt16(tbl.Rows.Count);
        for (int i = 1; i < num_row; i++)
        {
            string tstr = "txt" + i;
            tb = (TextBox)this.FindControl(tstr);

        }
        Label1.Text = tb.Text;
    }

asp 代码:

    <form id="form1" runat="server">
<div>
    <asp:Label ID="Label1" runat="server" Text="textbox value is"></asp:Label>
    <asp:Table ID="tbl" runat="server">
        <asp:TableRow ID="rw0">
            <asp:TableCell ID="c01" Width="100px">
                <asp:CheckBox runat="server" ID="chk0" />
            </asp:TableCell>
            <asp:TableCell ID="c02" Width="100px">
                <asp:TextBox runat="server" ID="txt0" />
            </asp:TableCell></asp:TableRow>
        <asp:TableRow ID="rw1">
            <asp:TableCell ID="c11" Width="100px">
                <asp:CheckBox ID="chk1" runat="server" />
            </asp:TableCell>
            <asp:TableCell ID="c12" Width="100px">
                <asp:TextBox runat="server" ID="txt1" />
            </asp:TableCell></asp:TableRow>
    </asp:Table>
    <asp:Button ID="btn1" runat="server" Text="Add Row" OnClick="addRow" />
</div>
<asp:Button ID="btnSubmit" runat="server" OnClick="btnSubmit_Click" Text="Submit" />
</form>

请协助我。

【问题讨论】:

  • 嗨,Alwyn,你能告诉我你在哪里有上面的代码吗?我的意思是在哪个事件或以哪种方法?
  • 嗨,Saranya,为了更清晰,我已经编辑了代码。
  • 我已经在底部发布了答案。请检查。
  • 您没有在 label1 中获得任何值的原因是,您的逻辑是标签中仅显示最后访问的文本框值。由于某种原因,动态创建的最后一个文本框的视图状态没有得到维护:(并且您的标签值为空
  • 发现错误。问题出在逻辑上。 int num_row = (int)Session["No_of_Rows"] + 1;删除 +1 并且它可以工作..而且你的逻辑是只有最后一个文本框的值显示在标签中。使用字符串生成器并将其附加到循环中以获得所有值。

标签: c# asp.net


【解决方案1】:

为了测试您的场景,我添加了 2 个控件 txtOutput 和 Getvalues 按钮。一切似乎都很好,除了您的控件 ID 从 0 开始,而您的 for 循环从 1 开始。

但是这不应该在 FindControl 中返回 null。

我怀疑您的表格 ID 不正确,因为在 您引用的另一篇文章中表格 ID 是“tbl”。

否则一切似乎都是正确的。无论如何,我已经粘贴了我在这里尝试过的代码,它可以工作。

您会得到错误的另一种可能性是,如果您在 Page_Load 中创建控件之前尝试访问这些控件。但是,因为您的表中有 2 行是静态的,所以无论动态控件的创建如何,您的代码都应该可以工作。请尝试以下代码并更新

<form id="form1" runat="server">
        <div>
        <div>
        <asp:Table ID="tbl" runat="server">
            <asp:TableRow ID="rw0">
                <asp:TableCell ID="c01" Width="100px">
                    <asp:CheckBox runat="server" ID="chk0" />
                </asp:TableCell>
                <asp:TableCell ID="c02" Width="100px">
                    <asp:TextBox runat="server" ID="txt0" />
                </asp:TableCell></asp:TableRow>
            <asp:TableRow ID="rw1">
                <asp:TableCell ID="c11" Width="100px">
                    <asp:CheckBox ID="chk1" runat="server" />
                </asp:TableCell><asp:TableCell ID="c12" Width="100px">
                    <asp:TextBox runat="server" ID="txt1" />
                </asp:TableCell></asp:TableRow>
        </asp:Table>
        <asp:textbox runat="server" id="checkIn" ClientIDMode="Static" name="checkIn" ></asp:textbox>
        <asp:Button ID="btn1" runat="server" Text="Add Row" OnClick="addRow" />
        <br />
        <asp:Button ID="GetValues" runat="server" Text="GetValues" OnClick="GetValuesfromDynamicControls" />
        <asp:TextBox ID="txtOutput" runat="server" />

//后面的代码从这里开始

 public partial class DynamicControl : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

            if (IsPostBack)
            {
                int num_row = (int)Session["No_of_Rows"];
                for (int i = 2; i < num_row; i++)
                {
                    TableRow row = new TableRow();
                    TableCell cell1 = new TableCell();
                    TableCell cell2 = new TableCell();
                    TextBox tb = new TextBox();
                    CheckBox cb = new CheckBox();

                    row.ID = "rw" + i;

                    cell1.ID = "c" + i + "1";
                    cell2.ID = "c" + i + "2";

                    tb.ID = "txt" + i;
                    tb.EnableViewState = true;
                    cb.ID = "chk" + i;

                    cell1.Controls.Add(cb);
                    cell2.Controls.Add(tb);

                    row.Cells.Add(cell1);
                    row.Cells.Add(cell2);

                    tbl.Rows.Add(row);
                }
            }
            else
            {
                Session["No_of_Rows"] = 2;
            }
        }

        protected void addRow(object sender, EventArgs e)
        {
            int num_row = (int)Session["No_of_Rows"];
            TableRow row = new TableRow();
            TableCell cell1 = new TableCell();
            TableCell cell2 = new TableCell();
            TextBox tb = new TextBox();
            CheckBox cb = new CheckBox();

            row.ID = "rw" + num_row;

            cell1.ID = "c" + num_row + "1";
            cell2.ID = "c" + num_row + "2";

            tb.ID = "txt" + num_row;
            tb.EnableViewState = true;
            cb.ID = "chk" + num_row;

            cell1.Controls.Add(cb);
            cell2.Controls.Add(tb);

            row.Cells.Add(cell1);
            row.Cells.Add(cell2);

            tbl.Rows.Add(row);
            Session["No_of_Rows"] = tbl.Rows.Count;
        }


        protected void GetValuesfromDynamicControls(object sender, EventArgs e)
        {
            //int rows =Convert.ToInt32( Session["No_of_Rows"]);
            int rows = Convert.ToInt32(tbl.Rows.Count);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < rows; i++)
            {               
                    TextBox tb =(TextBox) Page.FindControl("txt" + i);
                    sb.Append(tb.Text + ";");                
            }

            txtOutput.Text = sb.ToString();
        }

    }

【讨论】:

  • 你解决了我的两个大问题。所以我想给你牛奶丝 B-) .. 让我知道你是否愿意报销:)
  • 仅供参考:您提供的代码独立工作。但如果我将它合并到应用程序代码中,它就不起作用。后来我意识到它是因为母版页。这就是为什么我变得空了。为此,我们需要给出 tb = (TextBox)sometable.FindControl("txt" + i);
【解决方案2】:

在每次回发时,动态创建的控件可能不可见。因此,您需要在每个回帖上重新创建动态控件。然后您可以访问这些控件。

【讨论】:

  • 我已经完成了这一步 Priya。但我无法访问它。这就是我所做的stackoverflow.com/questions/19562117/…
  • 那么您在某处做错了什么,动态控件以这种方式工作,每次回发时,在页面加载事件中,您需要使用相同的 IDS 重新创建动态控件,您的被创造。假设第一次,您正在创建一个文本框(ID 为 txt1)和一个下拉控件(ID 为 drp1),然后如果您单击下拉,则意味着 POSTBACK 发生,然后是 Page-Load 事件,您需要重新创建 txtbox 和下拉控件具有相同的 ID:txt1 和 drp1,只有这样您才能进一步访问这些控件。
  • 我也做了同样的事情。在页面加载事件下,我使用 for 循环重新创建了所有控件。在添加行按钮事件中,我添加了新行。是的,我错过了一些地方。等一下,我会发布整个代码,以便您有空闲时间可以弄清楚:)。非常感谢。
【解决方案3】:

试一试:

            tb = (TextBox)sometable.FindControl("txt" + i);

【讨论】:

  • 哇 PJM。如果我们有母版页,这真的很有用。非常感谢朋友。但是如果我们没有masterpage,那么我们可以直接使用this.control或page.control,就像上面Saranya所说的那样
  • FindControl() 仅当控件直接包含在指定容器中时才会找到该控件;也就是说,该方法不会在控件内的控件层次结构中进行搜索,这就是为什么您需要指定命名容器 table。
  • 这个问题的答案应该和这个一样简单明了。
【解决方案4】:

你可以这样做:

TextBox txt= (TextBox)FindControl("txt"+i.Tostring());
string txtValue=txt.Text;

并在 for 循环中访问所有文本框:

int num_row = Convert.ToInt16(sometable.Rows.Count);
for (int i = 1; i < num_row; i++)
{
    string txtID="txt" + i.Tostring();
    TextBox txt= (TextBox)FindControl(txtID);
    string txtValue=txt.Text;
}

【讨论】:

  • @ChrisFarmer 尽管他没有获得正确的文本框 ID,但他没有将 i 转换为字符串:FindControl("txt" + i);
  • 我认为这不是真的。使用+ 会自动进行转换。 stackoverflow.com/questions/751303/…
  • 他 Karam :实际上我得到了正确的 id。我放了断点并检查了。但是我照你说的做了。结果还是一样。
  • @AlwynMiranda 你在哪里声明了 tb ?你在哪里打电话 tb ?请注意,您在 for 中多次分配给 tb 并且您在 for 循环之后调用 tb.Text !
  • tb 在块之前声明为:TextBox tb = new TextBox();
猜你喜欢
  • 2013-12-27
  • 2012-11-03
  • 2017-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-20
  • 2010-12-02
  • 2017-12-01
相关资源
最近更新 更多