ASP表行数没有增加

时间:2014-07-31 01:05:19

标签: c# asp.net dynamic

我有一个ASP表,第一行有一个下拉列表和文本框。我点击了一个按钮,应该添加一个类似的行。我的按钮单击事件中有以下功能。

public void addRow()
{
    int flag = Table1.Rows.Count;
    DropDownList ddl = new DropDownList();
    ddl.ID = "ddl" + (flag + 1).ToString();
    TextBox tBox = new TextBox();
    tBox.ID = "txt" + (flag + 1).ToString();
    TableCell tCell1 = new TableCell();
    TableCell tCell2 = new TableCell();
    tCell1.Controls.Add(ddl);
    tCell2.Controls.Add(tBox);
    TableRow tRow = new TableRow();
    tRow.Cells.Add(tCell1);
    tRow.Cells.Add(tCell2);
    Table1.Rows.Add(tRow);
}

添加第二行时,此代码正常工作。当我再次单击该按钮时,应该具有表的行数值的flag的值不会增加。因此不会创建新行。你能否告诉我为什么flag的值不会增加?或者他们是一个更容易的方法吗?直接回答或链接会有所帮助。

为表格标记代码:

<asp:Table ID="Table1" runat="server" Width="410px">
    <asp:TableRow>
    <asp:TableCell>
    <asp:DropDownList runat="server" ID="ddl1"></asp:DropDownList>
    </asp:TableCell>
    <asp:TableCell>
    <asp:TextBox runat="server" ID="txt1"></asp:TextBox>
    </asp:TableCell>
    </asp:TableRow>
    </asp:Table>

2 个答案:

答案 0 :(得分:1)

这里的问题是您不理解the ASP.Net Page Lifecycle,更重要的是它与dynamic controls(您添加的控件)的交互方式。

不幸的是,我们无法在不了解这些&#34;动态&#34;中的值的情况下回答这个问题。创建的控件用于服务器端或客户端。

我可以猜到:

1)如果它们用于客户端消费/使用,那你就错了。如果您需要更多信息,请询问另一个(更具体的)问题。

2)如果它们用于服务器端消费/使用,则每次回发只允许一个新记录,并且应该包含&#34; Save&#34;按钮,将保存当前&#34;新&#34;行并导致用户可以添加新条目的页面刷新。

3)参见规则#0(每条规则都有例外。{此规则适用于您理解手头的问题。})

答案 1 :(得分:1)

警告 - 丑陋的文本块

我将尝试解释为什么你要做的事情并不像它听起来那么简单(或者像我希望的那样简单)并且乐意给你一个改变的方法,当它 可能不是直截了当,应该是“更好”。

以下是对您要执行的操作的高级概述:

  

在完成保存之前,让用户有机会将一个或多个记录添加到集合(数据库)。

可以使用回发来执行此操作,以便在单击最终保存按钮时生成其他行/项。将鼠标悬停在这可能不是最简单或最好的方法。

从技术角度来看,添加动态控件必须在ASP.net page lifecylce的特定点以非常具体的方式进行。动态控件也必须在每次回发时重新创建,因此每次用户单击“添加”按钮时,除了新行之外,您还必须重新创建已有的行。这就是为什么你只得到这个例子中的一行。这就是添加dynaimc控件。等到你从动态文本框中获取数据并下载!

从最终用户的角度来看,这种方法也不理想,因为每次用户点击“添加”按钮时,页面都会循环执行请求/响应过程,这会在minumun中产生一些难看的闪存。

<强>更新

但是怎么样?我听你问。在这里它是(我已将其简化为此示例中的一列):

<强> ASPX

<asp:Table ID="Table1" runat="server">
    <asp:TableRow>
        <asp:TableCell><asp:TextBox ID="txt1" runat="server"> </asp:TextBox></asp:TableCell>
    </asp:TableRow>
 </asp:Table>

 <asp:Button ID="btnAdd" runat="server" Text="Add" onclick="Button1_Click" />
 <asp:HiddenField ID="hdnRowCount" runat="server" />
 <asp:Button ID="btnSave" runat="server" onclick="btnSave_Click" Text="Save" />

 <div>
     <asp:Label ID="lblResult" runat="server" Visible="false"></asp:Label>
 </div>

<强> C#

private int rowCount = 1;
private bool rowNeeded = false;

protected override void OnPreInit(EventArgs e)
{
    //Pre-emptively create additional row on post back.
    //We'll remove it if we don't need it later

    //Controls Have to be added at pre-init to maintain their view state
    //Adding a row in the button click event will result in any data 
    //entered in that row dissapearing from viewstate on next post back
    if (IsPostBack)
    {
        //Get number of additional rows from hidden field
        //We're using a hidden form field and Request.Form
        //instead of ViewsState and hdnRowCount.value
        //because ViewState has not been loaded at this stage
        //of the page life cycle
        if (!string.IsNullOrEmpty(Request.Form["hdnRowCount"]))
        {
            rowCount = int.Parse(Request.Form["hdnRowCount"]);
        }

        for (int i = 0; i < rowCount; i++)
        {
            TableRow tr = new TableRow();

            TableCell tc = new TableCell();
            TextBox tb = new TextBox();
            // +2 as there are existing controls with "1", eg txt1
            tb.ID = string.Format("txt{0}",i+2);
            tc.Controls.Add(tb);
            tr.Cells.Add(tc);

            Table1.Rows.Add(tr);
        }

    }

    base.OnPreInit(e);
}        


//Add Row Click
protected void Button1_Click(object sender, EventArgs e)
{            
    //Hold number of additional rows in hidne field
    hdnRowCount.Value = (++rowCount).ToString();
    //Let the page know we need to keep the row
    rowNeeded = true;            
}

//An Exmple of how to get your data out
protected void btnSave_Click(object sender, EventArgs e)
{
    string s = "";

    //Iterate through the table rows finding the controls
    //Using count -1 as we still have the pre-emptive row
    for(int i = 0; i < Table1.Rows.Count-1; i++)
    {
        TextBox tb = (TextBox)Table1.Rows[i].FindControl(string.Format("txt{0}",i+1));
        s += "," + tb.Text;
    }

    lblResult.Text = s;
    lblResult.Visible = true;

}

protected override void OnLoadComplete(EventArgs e)
{
    //Get rid of pre-emptive row if we don't need it
    if (IsPostBack)
    {
        if (!rowNeeded)
        {
            Table1.Rows.RemoveAt(Table1.Rows.Count - 1);
        }
    }
    base.OnLoadComplete(e);
}

结束更新

那么,我该怎么做?客户端,是这个问题的答案。我会使用jQuery创建第一行的克隆。然后,您需要先调整表单字段的idname属性,然后再将新行附加到表中。您还需要一个隐藏的表单字段来跟踪隐藏行的数量。当您的用户最终点击“保存”按钮时,在C#端,从隐藏的旧版学校中获取您隐藏的其他行数,并使用Request.Form[]获取每个已添加字段的值。

在我的观点中,这将为最终用户提供更顺畅的体验。

另一个有点hacky选项,如果您有一个已定义的最大额外行数。为此,有一个mamimum行,表格中有表格控件。然后,您可以在aspx中使用visible="false",并在用户点击“添加”时使用回发将其更改为visible="true"。另一个选项是为行提供一个隐藏行的CSS类,然后使用javascript / jquery删除该类以使该行可见。