在OnInit()中获取控件值的最佳方法是什么?

时间:2010-02-23 17:11:01

标签: c# asp.net webforms

我最近阅读了this article on smart use of ViewState,我对在ViewState中没有不必要的静态数据特别感兴趣。但是,我也很好奇我是否可以为父子下拉菜单做同样的事情,比如经典的Country / CountrySubDivision示例。

所以我有这个标记:

    <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" />

这个代码隐藏:

    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);
    }

所以我注意到的第一件事是,即使EnableViewstatefalse,我的国家/地区控件的值也会在请求中保持不变,而无需额外的努力。甜。这是很多序列化的东西,我不需要通过表格提交的电子邮件发送。

然后我看到上面的示例带有一对父子下拉,我看到ddlCountry.SelectedValue是默认的,而Request.Form["ddlCountry"]反映了控件的值。

有没有办法保留EnableViewState = "false"而不诉诸Request.Form来获取从属控件的值?

2 个答案:

答案 0 :(得分:2)

  

然后我通过一对父子下拉来看到上面的例子,我看到ddlCountry.SelectedValue是默认的,而Request.Form [“ddlCountry”]反映了控件的值。

您看到此行为的原因是,在页面生命周期的那一点,Viewstate尚未加载。加载Viewstate时,它将从Request.Form对象值中获取,因此您可以看到正确的值。

答案 1 :(得分:2)

由于ASP.NET Page Life Cycle

您可以访问ddlCountry的OnSelectedIndexChanged方法中新选择的值。

Request.Form["ddlCountry"]是获取所选值的旧学校方式(经典ASP),但如果您使用WebForms,则可能更容易使用页面生命周期的流程。我发现WebForms有点奇怪来自经典的ASP,但是一旦你理解了页面生命周期,它就不那么糟了。