I recently read this article on smart use of ViewState and am particularly interested in not having unnecessary static data in ViewState. However, I'm also curious if I can do the same thing for a parent-child dropdown, like the classic Country/CountrySubDivision example.
So I have this markup:
<asp:DropDownList runat="server" ID="ddlCountry" DataTextField="Name" DataValueField="ID" EnableViewState="false" />
<asp:DropDownList runat="server" ID="ddlCountrySubdivision" DataTextField="Name" DataValueField="ID" EnableViewState="false" />
<asp:Button runat="server" ID="btnTest" />
And this codebehind:
public class Country
{
public string Name { get; set;}
public int Id { get; set; }
}
public class CountrySubdivision
{
public string Name { get; set开发者_开发技巧; }
public int Id { get; set; }
public int CountryId { get; set; }
}
protected override void OnInit(EventArgs e)
{
var l = new List<Country>();
l.Add(new Country { Name = "A", Id = 1 });
l.Add(new Country { Name = "B", Id = 2 });
l.Add(new Country { Name = "C", Id = 3 });
ddlCountry.DataSource = l;
ddlCountry.DataBind();
var l2 = new List<CountrySubdivision>();
l2.Add(new CountrySubdivision { Name = "A1", Id = 1, CountryId = 1 });
l2.Add(new CountrySubdivision { Name = "A2", Id = 2, CountryId = 1 });
l2.Add(new CountrySubdivision { Name = "B1", Id = 4, CountryId = 2 });
l2.Add(new CountrySubdivision { Name = "B2", Id = 5, CountryId = 2 });
l2.Add(new CountrySubdivision { Name = "C1", Id = 7, CountryId = 3 });
l2.Add(new CountrySubdivision { Name = "C2", Id = 8, CountryId = 3 });
// this does not work: always comes out 1 regardless of what's actually selected
var selectedCountryId = string.IsNullOrEmpty(ddlCountry.SelectedValue) ? 1 : Int32.Parse(ddlCountry.SelectedValue);
// this does work:
var selectedCountryIdFromFormValues = Request.Form["ddlCountry"];
ddlCountrySubdivision.DataSource = l2.Where(x => x.CountryId == selectedCountryId).ToList();
ddlCountrySubdivision.DataBind();
base.OnInit(e);
}
So the first thing I noticed is that even when EnableViewstate
is false
, my country control's value is persisted across requests with no extra effort. Sweet. That's a lot of serialized stuff I don't need to send across the wire on form submissions.
Then I came to the example above with a pair of parent-child drop downs, and I see that ddlCountry.SelectedValue
is defaulting whereas Request.Form["ddlCountry"]
is reflecting the control's value.
Is there a way to keep EnableViewState = "false"
without resorting to Request.Form
to get a dependent control's value?
Then I came to the example above with a pair of parent-child drop downs, and I see that ddlCountry.SelectedValue is defaulting whereas Request.Form["ddlCountry"] is reflecting the control's value.
The reason you are seeing this behavior is that at that point in the page's lifecycle, Viewstate hasn't been loaded. When Viewstate is loaded, it is taken from the Request.Form object values, so you are seeing correct values there.
Because of the ASP.NET Page Life Cycle
You'll have access to the newly selected value in the ddlCountry's OnSelectedIndexChanged method.
Request.Form["ddlCountry"]
is the old school way (classic ASP) of getting the selected value, but if you are using WebForms, it's probably easier to just go with the flow of the page life cycle. I found WebForms a little weird initailly coming from classic ASP, but once you understand the Page Life Cycle, it's not so bad.
精彩评论