实际上,这些动态创建的控件的状态值实际上是存在于viewstat中的,并且在页面回发过程中,asp.net也试图恢复这些值 ,但由于但是没有在page_load结束前重建这些状态所依附的控件(根据 UniqueID来唯一决定控件,因此给动态产生的控件设置id属性最重要),所以asp.net没有地方把状态放回控件。
由于控件不会放入ViewState。如果你在页面设计时放置一个控件,那么页面每一次实例化的时候都会重新根据设计代码所编译出的可执行代码,重新创建这个控件;而如果你在页面运行时动态产生一个控件,就要保证下一次页面page_load结束之前自己的代码中重建这个控件(因为page_load之后 asp.net会立刻给这个控件装载状态,关于asp.net页面的事件顺序,可以查看本站的其他文章)。
MSDN上提供了一种参考的方式,override页面的LoadViewState方法,因为该方法调用是在page_load事件之前,它可以保证这些动态控件在事件处理函数里面是可用的。下面是一个很简单的例子,例子很简单,页面上动态添加10个textbox,在viewstate里面保存一个标志位,表示是否动态添加了这些控件,在LoadViewState函数里进行判断,如果有这个标志,则重新加载这些控件。
以下是代码片段:
public
bool
IsDynamicLoadControl { get { object dynamic = ViewState["IsDynamicLoadControl"]; return dynamic == null ? false : true; } set { ViewState["IsDynamicLoadControl"] = value; } } protected override void LoadViewState( object savedState) { base.LoadViewState(savedState); if (IsDynamicLoadControl) { LoadTextBox(); } } protected void Page_Load( object sender, EventArgs e) { if (!IsPostBack) { LoadTextBox(); } } private void LoadTextBox() { for (int i = 0; i < 10; i++) { TextBox input = new TextBox(); input.ID = "input" + i.ToString(); this.form1.Controls.Add(input); } IsDynamicLoadControl = true; } |
最后可以进行测试一下:
以下是测试代码:
TextBox tb
=
this
.FindControl(
"
input0
"
)
as
TextBox; ClientScript.RegisterStartupScript( this .GetType(), "" , string .Format( " <script>alert('{0}')</script> " ,tb.Text)); |