Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 表中动态创建的文本框丢失了文本值_C#_Asp.net_Textbox - Fatal编程技术网

C# 表中动态创建的文本框丢失了文本值

C# 表中动态创建的文本框丢失了文本值,c#,asp.net,textbox,C#,Asp.net,Textbox,我有一个动态生成的表,在2列中有文本框。在回发过程中,文本框总是空的,即使我填充了它们。 该表的构建方式如下: protected void ddlScalaTaglie_SelectedIndexChanged(object sender, EventArgs e) { DataTable dtRighe = oTab.getScaleTaglieRighe(ddlScalaTaglie.SelectedValue); //dt is datata

我有一个动态生成的表,在2列中有文本框。在回发过程中,文本框总是空的,即使我填充了它们。 该表的构建方式如下:

  protected void ddlScalaTaglie_SelectedIndexChanged(object sender, EventArgs e)
    {
        DataTable dtRighe = oTab.getScaleTaglieRighe(ddlScalaTaglie.SelectedValue);

        //dt is datatable object which holds DB results.
        Table tbl = new Table();
        tbl.CssClass = "table table-striped  table-bordered table-responsive";

        TableRow tr;
        TableCell tcEU, tcUS, tcUK, tcQty, tcEAN;
        Label lbEU, lbUS, lbUK, lbQty, lbEAN;
        TextBox tbEU, tbUS, tbUK, tbQty, tbEAN, tbToFocus = null;

        foreach (DataRow dr in dtRighe.Rows)
        {
            tr = new TableRow();

            //ean
            tcEAN = new TableCell();
            tbEAN = new TextBox();
            tbEAN.ID = "txtEAN" + dr[0].ToString();
            tbEAN.Width = new Unit(100, UnitType.Percentage);
            tbEAN.Columns = 15;
            tcEAN.Controls.Add(tbEAN); 
            tr.Controls.Add(tcEAN);

            //Qty
            tcQty = new TableCell();
            tbQty = new TextBox(); 
            tbQty.ID = "txtQty" + dr[0].ToString(); 
            tbQty.TextMode = TextBoxMode.Number; 
            tcQty.Controls.Add(tbQty);
            tr.Controls.Add(tcQty);            

            tbl.Controls.Add(tr);
        }

        Session["tbl"] = tbl;

        divTaglieRighe.Controls.Add(tbl);
    }
当我点击“保存”按钮时,我必须在表格中循环并保存所有文本框。文本

这是我写的:

 ArrayList arrScarpaFigli = new ArrayList();
 Table tbl = (Table)Session["tbl"];
 foreach (TableRow row in tbl.Rows)
 {
     foreach (TableCell cell in row.Cells)
     {
        foreach (Control ctrl in cell.Controls)
        {
           //CONTROL IS TEXBOXT: EXTRACT VALUES//
            if (ctrl is TextBox)
            {
                TextBox txt = (TextBox)ctrl;
                arrScarpaFigli.Add(txt.Text);
             }
         }
      }
  }
问题是,如果我填写文本框,文本中总是有一个空字符串。 我填写表格的唯一时刻是在下拉列表的selectionChange上

我做错了什么?
提前感谢

会话
中存储
控件的实例是一个糟糕的想法,完全是错误的。控件属于它们的父页-它们应该在创建后立即添加到父页中,并且应该随父页一起消失

ASP.NET中动态创建的控件的问题是,您必须存储它们被创建的事实的指示器(以及再次创建它们所需的相关信息),并在所有后续回发中重新创建它们-不迟于
Page\u Load
。只有这样,这些控件才有机会从
Request
获取它们的值,而您也有机会从控件获取这些值

在您的代码中,存储在
会话
中的
的实例(及其所有行、单元格和文本框)永远不会反映任何客户端数据更改,也不会属于为处理后续回发请求而创建的

更新

这里需要了解的一个重要事实是,在处理由
ddlScalaTaglie
更改引起的回发并将hew html返回给客户端之后,页面实例就消失了。在下一个请求中,将创建页面的一个新实例,但它不知道上一个实例的控制树中添加了表这一事实。您在
Page\u Load
中的代码必须发现表单必须具有此表,并以与第一次创建时完全相同的方式创建表-行、单元格和文本框具有完全相同的
ID
s


然后,将这个新创建的表添加到
divTaglieRighe.Controls
之后,文本框将能够从
Request.Form
集合中提取它们的客户端值。

会话中存储
控件的实例是一个糟糕的想法,完全是错误的。控件属于它们的父页-它们应该在创建后立即添加到父页中,并且应该随父页一起消失

ASP.NET中动态创建的控件的问题是,您必须存储它们被创建的事实的指示器(以及再次创建它们所需的相关信息),并在所有后续回发中重新创建它们-不迟于
Page\u Load
。只有这样,这些控件才有机会从
Request
获取它们的值,而您也有机会从控件获取这些值

在您的代码中,存储在
会话
中的
的实例(及其所有行、单元格和文本框)永远不会反映任何客户端数据更改,也不会属于为处理后续回发请求而创建的

更新

这里需要了解的一个重要事实是,在处理由
ddlScalaTaglie
更改引起的回发并将hew html返回给客户端之后,页面实例就消失了。在下一个请求中,将创建页面的一个新实例,但它不知道上一个实例的控制树中添加了表这一事实。您在
Page\u Load
中的代码必须发现表单必须具有此表,并以与第一次创建时完全相同的方式创建表-行、单元格和文本框具有完全相同的
ID
s


然后,将这个新创建的表添加到
divtaglierghe.Controls
,文本框将能够从
Request.Form
集合中提取其客户端值。

您创建了一个名为
tbl
的表,并添加了两个
TextBox
,然后将表控件存储在会话
session[“tbl”]
并添加到
divtaglier控件中。最后,您试图从会话
session[“tbl”]
表中获取文本框数据,而不是添加在
divTaglieRighe
控件中的ViewState控件。您必须从表
tbl
控件中获取数据,该控件添加到
divTaglieRighe
控件中。

您已经创建了一个名为
tbl
的表,并添加了两个
文本框
,然后您将表控件存储在会话
会话[“tbl”
中,并添加到
divTaglieRighe
控件中。最后,您试图从会话
session[“tbl”]
表中获取文本框数据,而不是添加在
divTaglieRighe
控件中的ViewState控件。您必须从表
tbl
控件中获取数据,该控件添加到
divTaglieRighe
控件中。

您必须在每次页面加载时重新创建动态控件,以确保回发后保留其值。因此,您需要创建一个新方法,在每次加载页面时处理表的创建

protected void Page_Load(object sender, EventArgs e)
{
    //always create the controls on every page load if there is a value selected in ddlScalaTaglie
    if (!string.IsNullOrEmpty(ddlScalaTaglie.SelectedValue))
    {
        createTable(ddlScalaTaglie.SelectedValue);
    }
}

protected void Button1_Click(object sender, EventArgs e)
{
    //use findcontrol to find the Table inside the placeholder
    Table tbl = Page.FindControl("divTaglieRighe").FindControl("Table1") as Table;

    //loop all rows and cells in the Table
    foreach (TableRow row in tbl.Rows)
    {
        foreach (TableCell cell in row.Cells)
        {
            foreach (Control ctrl in cell.Controls)
            {
                //the control is a textbox
                if (ctrl is TextBox)
                {
                    //cast the control back to a textbox
                    TextBox tb = ctrl as TextBox;

                    //does the checkbox have a value, if so append the label
                    if (!string.IsNullOrEmpty(tb.Text))
                    {
                        Label1.Text += tb.Text + "<br>";
                    }
                }
            }
        }
    }

}

protected void ddlScalaTaglie_SelectedIndexChanged(object sender, EventArgs e)
{
    //no need to create the Table dynamically, that will be handled in Page_Load
    //this method is just a dummy to trigger a PostBack

    //you could remove this method and the OnSelectedIndexChanged from the DropDown
    //and just keep the AutoPostBack="true", that will also work
}

private void createTable(string value)
{
    DataTable dtRighe = Common.LoadFromDB();

    //create a new table WITH id, that is needed for findcontrol
    Table tbl = new Table();
    tbl.ID = "Table1";

    //loop all rows in the datatable
    foreach (DataRow dr in dtRighe.Rows)
    {
        TableRow tr = new TableRow();

        //ean
        TableCell tcEAN = new TableCell();
        TextBox tbEAN = new TextBox();
        tbEAN.ID = "txtEAN" + dr[0].ToString();
        tbEAN.Width = new Unit(100, UnitType.Percentage);
        tbEAN.Columns = 15;
        tcEAN.Controls.Add(tbEAN);
        tr.Controls.Add(tcEAN);

        //Qty
        TableCell tcQty = new TableCell();
        TextBox tbQty = new TextBox();
        tbQty.ID = "txtQty" + dr[0].ToString();
        tbQty.TextMode = TextBoxMode.Number;
        tcQty.Controls.Add(tbQty);
        tr.Controls.Add(tcQty);

        tbl.Controls.Add(tr);
    }

    //add the table to the placeholder
    divTaglieRighe.Controls.Add(tbl);
}
受保护的无效页面加载(对象发送方,事件参数e)
{
//如果在ddlScalaTaglie中选择了值,则始终在每次页面加载时创建控件
如果(!string.IsNullOrEmpty(ddlScalaTaglie.SelectedValue))
{
createTable(ddlScalaTaglie.SelectedValue);
}
}
受保护的无效按钮1\u单击(对象发送者,事件参数e)
{
//使用findcontrol查找占位符内的表
表tbl=第页FindControl(“divTaglieRighe”)。FindControl(“表1”)为表;
//循环表中的所有行和单元格
<asp:DropDownList ID="ddlScalaTaglie" runat="server" OnSelectedIndexChanged="ddlScalaTaglie_SelectedIndexChanged" AutoPostBack="true">
    <asp:ListItem Text="Select..." Value=""></asp:ListItem>
    <asp:ListItem Text="Option 1" Value="1"></asp:ListItem>
    <asp:ListItem Text="Option 2" Value="2"></asp:ListItem>
</asp:DropDownList>
<br />
<br />
<asp:PlaceHolder ID="divTaglieRighe" runat="server"></asp:PlaceHolder>
<br />
<br />
<asp:Button ID="Button1" runat="server" Text="Save" OnClick="Button1_Click" />
<br />
<br />
<asp:Label ID="Label1" runat="server" Text=""></asp:Label>