过去,在开发动态加载多控制单页类型应用程序时,我对viewstate感到非常头疼。原因是必须在OnInit阶段而不是后面添加控件。由于我正在处理一个控制事件(例如,下拉列表中的selectedIndexChanged ),所以我将它们加载到事件处理程序阶段。我知道孩子控制页面周期的追赶,但我注意到有时它只是不起作用。
我再次受命开发这样一个应用程序。这一次,我决定采取不同的方法。对于那些基于值加载动态控件的选择控件,我将在Request.Form阶段检查它们的回发响应值,并立即加载该控件。我不会从事件处理程序阶段加载任何动态控件,因为这是在OnPreRender之前,而且为时已晚。
总结如下:
在页面周期的早期从Request.Form集合(例如OnInit)检查控件的值,然后执行操作,而不是在页面周期的后面从实际控件中检查该值,有哪些缺陷呢?
发布于 2013-10-11 14:07:55
其中一个缺陷是,如果控件不包含在<form>中,它就不存在。我建议继续在事件处理程序阶段添加这些控件,因为这是您知道要添加什么的时候,但是要在ViewState或SessionState中存储重建这些控件所需的信息。
通过这样做,您将能够在OnInit中重新创建它们,但不必处理围绕着您现在要走的道路的一些其他复杂性。
所以,假设你发现你需要建立一个控制。你会建造它:
var tb = new TextBox();
tb.ID = "myTextBox";
...但是,您还可以保存必要的状态信息:
this.ViewState.StoreControl(typeof(TextBox), "myTextBox");然后构建扩展方法:
public static void StoreControl(this StateBag vs, Type controlType, string name)
{
var dynamicControls = vs["DynamicControls"] as List<Tuple<Type, string>>;
if (dynamicControls == null)
{
dynamicControls = new List<Tuple<Type, string>>();
vs["DynamicControls"] = dynamicControls;
}
var t = dynamicControls.FirstOrDefault(tp => tp.Item2 == name);
if (t == null) { dynamicControls.Add(Tuple.Create(controlType, name)); }
}然后在OnInit中,您可能会这样做:
var dynamicControls = vs["DynamicControls"] as List<Tuple<Type, string>>;
if (dynamicControls != null)
{
foreach (var tp in dynamicControls)
{
Control c = Activator.CreateInstance(tp.Item1) as Control;
c.ID = tp.Item2;
this.Controls.Add(c);
}
}注意:这段代码是在上写的。它没有被编译或调试。但你知道这个主意。
https://stackoverflow.com/questions/19320142
复制相似问题