我正试图围绕asp.net.我有一个很长时间的PHP开发人员的背景,但我现在面临学习asp.net的任务,我遇到了一些麻烦.这可能是因为我试图强迫框架进入它不适合的东西 - 所以我想学习如何"正确的方式".:-)
我的问题是如何在运行时以编程方式向页面添加控件.据我所知,你需要在page_init创建控件,否则它们会在下一个PostBack中消失.但很多时候我遇到的问题是我不知道要在page_init中添加哪些控件,因为它依赖于之前PostBack的值.
一个简单的场景可能是在设计器中添加了下拉控件的表单.下拉列表设置为AutoPostBack.当发生PostBack时,我需要根据下拉控件中的所选值来渲染一个或多个控件,并且最好使这些控件的行为好像它们已经被设计添加(如"回发时,行为正确").
我在这里走错了路吗?
我同意这里提出的其他观点"如果你可以动态地创建控件,那么就这样做......"(由@ Jesper Blad Jenson称为),但这是我在过去使用动态创建的控件制作的技巧.
问题变成了鸡肉和鸡蛋.您需要使用ViewState来创建控制树,并且需要创建控制树以获取ViewState.嗯,这几乎是正确的.有一种方法可以在填充树的其余部分之前获取ViewState值.这是通过压倒LoadViewState(...)
和SaveViewState(...)
.
在SaveViewState中存储您要创建的控件:
protected override object SaveViewState() { object[] myState = new object[2]; myState[0] = base.SaveViewState(); myState[1] = controlPickerDropDown.SelectedValue; return myState }
当框架调用"LoadViewState"覆盖时,您将获得从"SaveViewState"返回的确切对象:
protected override void LoadViewState(object savedState) { object[] myState = (object[])savedState; // Here is the trick, use the value you saved here to create your control tree. CreateControlBasedOnDropDownValue(myState[1]); // Call the base method to ensure everything works correctly. base.LoadViewState(myState[0]); }
我已经成功地使用它来创建ASP.Net页面,其中DataSet被序列化到ViewState以存储对整个数据网格的更改,允许用户使用PostBacks进行多次编辑,并最终在单个"保存"中提交所有更改操作.