The "status problem of dynamic controls" is very interesting:
Http://blog.joycode.com/saucer/archive/2004/10/20/35927.aspx
I hope to write such a logic to make Troubleshooting help. We can analyze this problem like this:
The first step is to simplify the Page. Built a new ASP.NET Web Application with the following code:
Private Void Page_Load (Object Sender, System.EventArgs E)
{
DropDownList DDLDYNAMIC = New DropDownList ();
DDLDYNAMIC.ID = "DDLDYNAMIC";
HTMLFORM FORM1 = (HTMLFORM) This.FindControl ("Form1");
IF (! ispostback)
{
DDLDYNAMIC.Items.Add ("before");
}
Form1.controls.add (ddldynamic);
IF (! ispostback)
{
DDLDYNAMIC.ITEMS.ADD ("after");
}
}
Throw a button on Page so you can postback. After running Postback results, "Before" Item is not retained, "After" is preserved. The problem is Isolate: The problem is not that the DropDownList or ListCollection has a problem with the process of the View State, but a specific one of the ListItem View State.
Now there is a goal, then look at ListItem Source Code:
INTERNAL OBJECT SaveViewState ()
{
IF (this.misc.get (2) && this.misc.get (3))
{
Return New Pair (this.text, this.value);
}
IF (this.misc.get (2))
{
Return this.Text;
}
IF (this.misc.get (3))
{
Return New Pair (null, this.value);
}
Return NULL;
}
You can see that only Misc.get (2) or Misc.get (3) meets a certain condition to save View State, in view of MISC is Private Member, continue in ListItem's Code what will affect Misc.get (2) or Misc. The value of GET (3), the results are as follows:
INTERNAL BOOL DIRTY
{
set
{
THIS.MISC.SET (2, Value);
this.misc.set (3, value);
}
}
Found the only possibility, see the Callee Graph of the Set method in the Reflector, find System.Web.ui.WebControls.listItemCollection.Add (ListItem): Void method. Continue to see Source Code:
Public Void Add (ListItem Item)
{
This.listItems.Add (item);
IF (this.marked)
{
Item.dirty = true;
}
}
Here is a private bool marked flag. Continue to find in ListItemCollection:
Internal void trackviewstate ()
{
THIS.MARKED = TRUE;
For (int Num1 = 0; NUM1 THIS [Num1] .trackViewState (); } } Void istateManager.trackviewState () { THIS.TRACKVIEWSTATE (); } Ok, it seems that this method is the key ... Because it is an interface method, we can try to call it in Page2: (DDLDYNAMIC.Items). TrackViewState (); if (! Ispostback) {for (INT i = 1; i <= 3; i ) ddldynamic.Items.Add (new ListItem (), i.toTString ()));} form1.controls.add (ddldynamic); It is really a role ... given this, we can guess the system.web.ui.webcontrols.listitemcollection.trackviewState () method. To prove that this is much easier ... With Windbg, set a breakpoint on the system.web.ui.webcontrols.listitemcollection.trackviewState () method. The Call Stack is as follows: 019cf8b0 06538fd0 [DEFAULT] [hasThis] Void System.Web.UI.WebControls.ListItemCollection.TrackViewState () 019cf8b4 06538fbe [DEFAULT] [hasThis] Void System.Web.UI.WebControls.ListControl.TrackViewState () 019cf8bc 06538e53 [DEFAULT] [ hasThis] Void System.Web.UI.Control.InitRecursive (Class System.Web.UI.Control) 019cf8d8 0653758a [DEFAULT] [hasThis] Void System.Web.UI.Control.AddedControl (Class System.Web.UI.Control, I4) 019cf8f4 06537462 [DEFAULT] [hasThis] Void System.Web.UI.ControlCollection.Add (Class System.Web.UI.Control) 019cf904 063c06fc [DEFAULT] [hasThis] Void WebApplication37.WebForm3.Page_Load (Object, Class System. EventArgs) at [ 0x13c] [ 0x8c] c: /inetpub/wwwroot/webapplication37/webform3.aspx.cs: 36 019cf944 065391a4 [DEFAULT] [hasThis] Void System.Web.UI.Control.OnLoad (Class System.EventArgs ) ... Ok ... everything is clear ...