asp.net在回发后动态添加用户控件保存值

这是我的问题。 我有一个usercontrol,我希望允许用户使用按钮单击添加任意数量的实例(每次单击一个按钮,我想将另一个用户控件实例添加到Panel)。 它第一次工作正常,但每个额外的回发删除所有添加的控件。 我跟踪用户添加的用户控件的数量没有问题,但我如何确保它们保持在回发之前的状态? 我已经阅读了一些关于使用SaveViewState和LoadViewState的人的post,但我找不到任何例子。

我最大的问题是确保每个用户控件的所有文本框和下拉列表在每个回发后都保持填充相同的文本/选定值/数据

提前谢谢,本

由于您是以编程方式向页面添加控件,因此您需要在每次回发时重新创建它们。

此外,您必须在页面的PreInitInit事件上重新创建以编程方式添加的控件。 这适用于正确的视图状态恢复事件管理。

如果你不这样做,控制将在回发时消失,他们将不会处理任何事件。

编辑

虽然建议在PreInitInit上添加动态控件,但是如果你在page_load上添加它可能会有效(如Dustin Hodges所说)。 除非你别无选择,否则你应该避免它。

您可以在Page_Load事件处理程序中加载控件并正确维护视图状态。
这完全取决于您是否以编程方式设置动态加载控件的任何属性,如果是,则相对于Controls.Add(dynamicControl)行进行此操作。
对此的深入讨论有点超出了本文的范围,但它可能起作用的原因是因为Controls属性的Add()方法以递归方式将父视图状态加载到其子节点中,即使已经过了加载视图状态阶段。

来源MSDN

如果要跟踪用户添加的控件数量,则需要重新创建用户之前添加的控件,最好是在Page_Init或Page_Load中。 将这样的内容添加到该处理程序:

 for(int i=0; i 

如果你这样做,应该保持控件的状态,因为当你将tb控件添加到控件集合时,它会捕获事件并应自动恢复其viewstate。

您不必在会话中跟踪其状态,因为在大多数情况下,它将存储在视图状态中

我有一个噩梦,试图在一个旧项目上解决这个问题。 在中间阶段,我发现我对网络开发的了解远远少于我的想法(阅读这个网站是一个很好的方式来谦卑自己每天 – 如果不是每小时 – 基础上)。 在那个项目中,Page.IsPostBack对我来说完全没用,因为我已经动态地实例化了控件。

话虽这么说,我建议的最好的事情是考虑使用Session变量。 如果你有一个类(或类的集合)代表你从页面捕获的数据,那么也许最容易在该类/集合中存储值以提高代码可读性,然后将其写入会话。

查看您的PageLoad并在清除面板的行之前添加if(!this.IsPostBack)

这当然只是一个猜测,但我已经看到很多问题,问题与此有关

我认为可能发生的事情是当你点击按钮添加, Page_Load fires会为你创建一个全新的页面。 然后,按钮单击方法添加控件,页面完成渲染。 当您第二次单击它时, Page_Load会创建您的页面,再次按钮单击方法会创建一个控件并将其添加到页面中。 不幸的是,你之前添加的那个不再存在。

如果您将控件添加到Repeater会怎样? Repeater的视图状态可以跟踪您添加的每个控件,以便在回发后,它不会被吹走。

如果您有大量用户,这是一个丑陋的解决方案,但您可以将用户控件自己粘贴到会话中。 我使用页脚控件执行此操作,因为每次页面更改以重新创建页脚时我都不想访问数据库。

如果您拥有大量用户并且他们使用此function,则此解决方案可以在服务器上获得真正的任务。 至少我认为它会……

但是你可以在page_load上重新填充其中包含usercontrols的占位符。 我可以很快提出一个例子。

我做的例子:

 if (Session["footer"] == null) { Session["footer"] = new Footer(LinksRules.BuildFooterLinks((int)WebSiteSections.Main));// where Footer is my control } footerPH.Controls.Add((Footer)Session["footer"]); 

像单身模式一样……

因此,我认为你可以在任何会导致回发的事情上做到这一点

Session [“DynamicControls”] = PlaceHolder.Controls;

在页面加载方法中,您可以:

 foreach(var control in (List)Session["DynamicControls"]) { yourPlaceHolder.Controls.Add(control); } 

如果会话对象为null,只需添加一个就像他们从未去过那里一样。

我相信这会像你想要的那样依赖于控件内部的数据。