我有一个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>
答案 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创建第一行的克隆。然后,您需要先调整表单字段的id
和name
属性,然后再将新行附加到表中。您还需要一个隐藏的表单字段来跟踪隐藏行的数量。当您的用户最终点击“保存”按钮时,在C#端,从隐藏的旧版学校中获取您隐藏的其他行数,并使用Request.Form[]
获取每个已添加字段的值。
在我的观点中,这将为最终用户提供更顺畅的体验。
另一个有点hacky选项,如果您有一个已定义的最大额外行数。为此,有一个mamimum行,表格中有表格控件。然后,您可以在aspx中使用visible="false"
,并在用户点击“添加”时使用回发将其更改为visible="true"
。另一个选项是为行提供一个隐藏行的CSS类,然后使用javascript / jquery删除该类以使该行可见。