下面的代码在每次回发时,仍能保持5个Item:
private void Page_Load(object sender, System.EventArgs e)
{
ddl = new DropDownList();
this.PlaceHolder1.Controls.Add(ddl);
if (!IsPostBack)
{
for (int i = 0; i < 5; i++)
{
ddl.Items.Add(i.ToString());
}
}
}
思归如是说:
其一开始是新建对象,处于原始状态,当它被加到父控件的Controls里时,父控件会根据其当前的control阶段来调用该子控件的一些方法,让子控件赶上父控件的control阶段 (这些方法可以从上个贴里leighsword和microhelper贴的Control的AddedControl方法里看到,在此就不重复了,而且也不用看那些方法)。为什么要这样呢?这应该跟整个页面的生命周期有关吧。
但大概来讲,当我们在Page_Load里调用form1.Controls.Add()时,父控件form1处于Load阶段(上面的第六行),它就会调用下拉框的一些方法让它经过Init->Load状态,其中的一个结果是在Init后面调用了TrackViewState,DropDownList的父类ListControl, override了TrackViewState,在其中调用了Items(ListItemCollection类)对象的TrackViewState。其结果是,如果你在form1.Controls.Add()之后改变动态DropDownList控件的Items的话,那些ListItem就会被保存下来,因为ListItemCollection对象 override 了 SaveViewState() 。而在form1.Controls.Add()之前添加的ListItem则不会被保存下来。
而这个控件的SelectedIndex是什么时候被赋成正确的值了(页面回发的选中的值):
System.Web.UI.Page
private void ProcessRequestMain()
base.LoadRecursive(); //call this.OnLoad(EventArgs.Empty);
if (this.IsPostBack)
{
this.ProcessPostData(this._leftoverPostData, false);
}
System.Web.UI.Page
private void ProcessPostData(NameValueCollection postData, bool fBeforeLoad)
foreach (string text
1 in
postData)
{
Control control1 = this.FindControl(text1);
IPostBackDataHandler handler1 = (IPostBackDataHandler) control1;
handler1.LoadPostData(text1, this._requestValueCollection);
}
System.Web.UI.WebControls.DropDownList
bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection)
string[] textArray1 = postCollection.GetValues(postDataKey);
int num1 = this.Items.FindByValueInternal(textArray1[0]);
this.SelectedIndex = num1;