代码之家  ›  专栏  ›  技术社区  ›  Josh Kodroff

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

  •  2
  • Josh Kodroff  · 技术社区  · 16 年前

    我最近看了 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);
        }
    

    所以我注意到的第一件事就是 EnableViewstate false ,我的国家/地区控制的价值在所有请求中都是持久的,不需要额外的努力。太好了。这是很多系列化的东西,我不需要在提交表单时跨线发送。

    然后我用一对父子下拉列表来举上面的例子,我看到了 ddlCountry.SelectedValue 违约,而 Request.Form["ddlCountry"] 正在反映控件的值。

    有办法保持 EnableViewState = "false" 不诉诸 Request.Form 要获取依赖控件的值?

    2 回复  |  直到 16 年前
        1
  •  2
  •   Gabriel McAdams    16 年前

    然后我用一对父子下拉列表来举上面的例子,我看到ddlCountry.SelectedValue是默认值,而request.form[“ddlCountry”]则反映控件的值。

    您看到这种行为的原因是,在页面的生命周期中,此时还没有加载viewstate。加载viewstate时,它是从request.form对象值中获取的,因此您可以看到正确的值。

        2
  •  2
  •   nickytonline    16 年前

    因为 ASP.NET Page Life Cycle

    您将可以访问DDL国家/地区的OnSelectedIndexChanged方法中新选择的值。

    Request.Form["ddlCountry"] 是获取所选值的传统方法(经典ASP),但是如果您使用WebForms,那么只使用页面生命周期的流程可能更容易。我发现webforms最初有点奇怪,它来自于经典的ASP,但是一旦你理解了页面的生命周期,它就没有那么糟糕了。