【问题标题】:Cannot add more than one row to a table dynamically using ASP/C#无法使用 ASP/C# 向表动态添加多于一行
【发布时间】:2013-07-01 13:47:33
【问题描述】:

我有一个带有 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);
}

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

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

我该怎么做呢?

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

【问题讨论】:

  • 这是因为表在回发时被重置。
  • @Darren 说的是正确的。按钮回发正在将表重置回其原始状态。您可以尝试仅将按钮包装在 UpdatePanel 中,这将仅发回按钮而不是整个页面。
  • @Darren 我也很怀疑。有没有办法解决这个问题?
  • 如果您对 page_load 中的表格进行任何操作,请将其包装在 if(!IsPostBack){}
  • 你的做法行不通。如果我们知道您想要达到的目标,我们可以向您推荐一种替代方法。

标签: c# asp.net html-table


【解决方案1】:

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

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

我假设您熟悉 Javascript,但您可以将客户端事件绑定到服务器端按钮 - 只需添加 onclientclick="insertRow();" 其中onclientclick 是按钮控件的属性,insertRow() 是 Javascript 方法在您的页面中定义在 &lt;script&gt;&lt;/script&gt; 标记之间。

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

【讨论】:

  • 感谢您的回复!它回发到服务器的原因是因为它正在读取 XML。关于我如何到达这里的真正漫长的故事是,有一个可以填写、保存和加载的巨大表单。虽然每个部分的行数是未知的,我没有直接输入 20 行,而是输入了 3 行,当它看到你在最后一行中输入了一个字符时,表格会简单地动态扩展部分。这是由 jQuery 处理的。
  • 问题在于加载。默认情况下,基本 HTML 每个部分仍然有 3 行,但如果 XML 文件在该部分中显示超过 3 个条目,则它必须能够扩展,并且这是在服务器端完成的。我实际上想出了一个成功的方法......有点(输入框被视为 LiteralControls,而不是 HTMLInputBoxes)。但这就是我来到这里的方式。如果您认为该系统有更好的实施方式,我会全力以赴,但我可能无法返回并更改以前构建的基础架构。
【解决方案2】:

其他答案表达的观点是完全正确的,因为这种架构存在很大缺陷(它的工作方式与 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 疯狂的唯一方法。

【讨论】:

  • 这似乎是个好智慧。我会看看转移到客户端需要什么,因为当我说我非常愿意这样做时,请相信我。对于初学者来说,已经调整表格的所有内容都已经用 jQuery 写出来了,因此这个项目的特定抽象已经存在,它就像一个函数调用一样简单,可以让它做我想做的事情。不过,我真的很感激这种洞察力。在我看来,能够描绘出这将采取的行动是非常宝贵的。
猜你喜欢
  • 1970-01-01
  • 2012-11-27
  • 2013-11-04
  • 2019-02-12
  • 1970-01-01
  • 2014-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多