If I set on my page : EnableViewState=\"true\" ViewStateMode=\"Disabled\"
- Then - the Viewstate is disable for the page ( unless override...)
The
The SelectedValue
relies on ViewState
because on PostBack it rebuilds its ListItems
from the ViewState
and then sets the selected value on the DropDownList
from the Request
Object.
It is not taking the Request
value as the SelectedValue
directly. This in turn is because, ASP.Net can check if the posted DropDownList
has not been tampered with at the client. It does so by first de-serializing the original items from the ViewState
. It then finds the Request
Value in the items and sets its Selected
property as true
. Only now, the SelectedValue
property is available. (or SelectedIndex
for that matter). It should be able to fire a SelectedIndexChanged
event now.
This is also the reason that you do not need to bind the DropDownList
again in PageLoad
. The list items are automagically retreived from the ViewState
.
If the ViewState
is disabled, then there will be no original list items in the ViewState
and will be empty. Hence it will not be able to mark any item as selected. Hence the SelectedValue
will be 0 or the SelectedItem
will be null. I think the SelectedIndexChanged
event will also not fire. For things to work in this case databinding needs to be done, preferably on init
.
There are workarounds to that however.
Complete Reference: http://msdn.microsoft.com/en-us/library/ms972976.aspx
Edit: (after Op's comments)
Following the page life cycle to see where SelectedValue
relies on ViewState
:
Stage 1 Init: The control heirarchy is built. If the DropDownList is bound here or the ListItems have been added declaratively, the List gets populated here.
Stage 2 Load ViewState: On PostBack, the ViewState is validated here and loaded into the DropDownList. There is no SelectedValue
here.
Stage 3 Load PostBack Data: Here the Request
Value (from the form request) is taken and then applied to the control. In this case of DropDownList
it now sets the SelectedValue
from the received Request
Object Value, internal implementation is something like this:
string selectedValue = HttpContext.Current.Request.Form[DropDownList_Id];
Items.FindByValue(selectedValue).Selected = true;
What is important here is that if ViewState is not there and DropDownList is not data-bound, then the ListItem collection will be empty and hence SelectedValue
property is 0. This has nothing to do with internal implementation of a property.
If the ViewState is not there (disabled) and DropDownList is data-bound, then the ListItem collection will exist and corresponding item will be marked as selected and hence SelectedValue
property will return the correct value.
If the item collection is new (thru a re-binding with different data set or ViewState is invalidated), then the Request
Form value would not be found in the item collection and again SelectedValue
will be invalid.
Stage 4 Page Load: by this time the ViewState (or data-binding) and PostBack Data has already been loaded.
Stage 5 Raise PostBack Event: At this stage the OnSelectedIndexChanged
event of DropDownList is fired if the index was changed in Stage 3.
Hence, the SelectedValue
relies on ViewState at Stage 3. Of course, if the control is appropriately data-bound then it will not rely on ViewState as a corollary.
SelectedValue
relies on ViewState to make sure the items collection has been populated prior to setting it. Data-binding / Re-binding is just another way to make sure the items collection is populated.
Hope that clarifies.