2

我有一个带有 HTML 表格的 Web 应用程序,其中到处都包含输入框。我希望能够从 C# 方面向这些表中添加行。为此,我使用了一个调用此方法的 asp 按钮:

private void AddRow()
{
    HtmlTableRow tRow = new HtmlTableRow();

    HtmlTableCell cell = new HtmlTableCell();
    HtmlTableCell cell2 = new HtmlTableCell();
    HtmlTableCell cell3 = new HtmlTableCell();
    HtmlTableCell cell4 = new HtmlTableCell();

    cell.InnerHtml = "<input type=\"text\" size=\"29\">";
    tRow.Cells.Add(cell);

    cell2.InnerHtml = "<input type=\"text\" size=\"9\" class=\"units commas\" />";
    cell2.Attributes.Add("class", "leftBorder textCenter");
    tRow.Cells.Add(cell2);

    cell3.InnerHtml = "<input type=\"text\" size=\"8\" class=\"value commas\" />";
    cell3.Attributes.Add("class", "leftBorder textCenter");
    tRow.Cells.Add(cell3);

    cell4.InnerHtml = "<input type=\"text\" size=\"11\" readonly=\"readonly\" tabindex=\"-1\" class=\"totalA1 autoTotal\" />&nbsp;";
    cell4.Attributes.Add("class", "leftBorder rightBorder textRight");
    tRow.Cells.Add(cell4);

    someTable.Rows.Add(tRow);
}

这很好用……正好是一排。我可以单击按钮,它会添加一行。如果我再次单击它,它不会做任何事情。更具体地说,我怀疑它正在删除当前添加的行,将文档恢复到“默认”状态,然后添加一行(实际上什么都不做)。

假设我是对的,我需要能够以某种方式将一行附加到另一个动态创建的行,而不是仅仅替换它。如果我错了,我只需要一种能够在按下按钮时不断添加行的方法。

我该怎么做呢?

编辑:我应该指定,所有这些都可以一次循环完成。为了测试,我希望让它在按下按钮时工作,但它都可以整齐地塞进某种循环中。我已经(一些)成功地将它放在了一个中。

4

2 回答 2

3

做你需要的绝对最好的方法是客户端,而不是服务器端。对于您正在做的事情,每次插入新行(在我看来)回发到服务器是没有意义的。是否有特定原因必须执行此服务器端(C#)?

使用 Javascript (jQuery) 在单击按钮时将新行动态插入到表中。该页面不会刷新,它更快,并且可以提供更好的用户体验。

我假设您熟悉 Javascript,但您可以将客户端事件绑定到服务器端按钮 - 只需添加onclientclick="insertRow();"whereonclientclick是按钮控件的属性,并且insertRow()是页面中定义的 Javascript 方法<script></script>

如果您需要我写一个有关如何执行此操作的示例,请告诉我,我可以编辑我的答案。

于 2013-07-03T19:48:23.000 回答
1

其他答案所表达的观点是完全正确的,因为这种架构存在很大缺陷(它的工作方式与 2000 年代中期,一生前在网络中所做的事情一样)。话虽这么说,你有限制,你不能改变它们。以下是我要检查的两件事,其中一件事已经在评论中提出:

  1. 回发干扰表初始化。当访问者首次加载您的 aspx 页面时,浏览器将对您的页面执行 HTTP GET 请求。您的 aspx 页面类的 IsPostback 属性将为 false。当用户单击您的按钮时,他们将对您的 aspx 页面发出 POST 请求,如果他们在浏览器上修改了页面的当前状态以及一组特定于 .NET 的属性,则传递一堆变量以表示页面的当前状态指示按下了什么以及服务器应该执行什么事件处理程序(在您的情况下,将调用调用 AddRow 的事件处理程序,但仅在首先执行 Page_Load 之后)。这就是为什么他们建议将您的 Page_Load 逻辑包装在 if(!IsPostback){} 中。

  2. 没有为 HtmlTable 控件启用 ViewState。ViewState 是 .NET 特定的实现,它将服务器所知道的关于 HTML(输入框等)的所有信息序列化到输出 HTML 中的隐藏字段中。如果您希望 .NET 记住各种 HTML 标记的状态(它们包含什么、用户在每个标记中填写的内容等),那么它们需要在 ViewState 中有一个条目,该条目从回发传递到回发. 但是请注意,一旦有人在没有单击按钮或使用浏览器上的后退和前进按钮的情况下刷新页面(因为请记住它们对应于 HTTP GET 请求,而不是 HTTP POST 请求),无论如何都会重新初始化视图状态。解决此问题的唯一方法是将内容塞入会话中。如果您对此感到满意,那么要启用视图状态,请使用 . HtmlTable 控件上的 EnableViewState() 方法,但请记住,这会增加 Web 应用程序的页面大小,因为 .NET 会将表包含的内容序列化为字符串并将其放入隐藏的输入变量中。这将使编写所有服务器端逻辑变得“容易”,但如果表变得非常大,则会付出巨大的代价。

现在看来,阻力最小的途径就是让现有的基础设施正常工作,但请相信我,你正在招致越来越多的技术债务,无论是你还是其他人都必须偿还。我强烈建议使用客户端添加行方法,这是解决 web 表单中这种 postback-viewstate-model 疯狂的唯一方法。

于 2013-07-03T21:22:16.950 回答