11

我创建了一个基本绑定两个下拉列表的服务器控件,一个用于国家和一个用于状态,并更新该国的selectedindexchanged事件的状态下拉列表。但是,它不会回发。任何想法为什么?在一个UpdatePanel包装他们(有呈现问题;也许是因为我没有一个页面引用?)积分ASP.NET/C#:DropDownList SelectedIndexChanged在服务器控件中未触发

这里是我有(有一些额外的数据访问的东西剥离出来):

public class StateProv : WebControl 
{ 
    public string SelectedCountry; 
    public string SelectedState; 

    private DropDownList ddlCountries = new DropDownList(); 
    private DropDownList ddlStates = new DropDownList(); 

    protected override void OnLoad(EventArgs e) 
    { 
     base.OnLoad(e); 

     IList<Country> countries = GetCountryList(); 
     IList<State> states = new List<State>(); 

     if (SelectedCountry != null && SelectedCountry != "") 
     { 
      states = GetStateList(GetCountryByShortName(SelectedCountry).CountryShortName); 
     } 
     else 
     { 
      states.Add(new State { CountryId = 0, Id = 0, StateLabelName = "No states available", StateLongName = "No states available", StateShortName = "" }); 
     } 

     ddlCountries.DataSource = countries; 
     ddlCountries.DataTextField = "CountryLongName"; 
     ddlCountries.DataValueField = "CountryShortName"; 
     ddlCountries.SelectedIndexChanged += new EventHandler(ddlCountry_SelectedIndexChanged); 
     ddlCountries.AutoPostBack = true; 

     ddlStates.DataSource = states; 
     ddlStates.DataTextField = "StateLongName"; 
     ddlStates.DataTextField = "StateShortName"; 

     ddlCountries.DataBind(); 
     ddlStates.DataBind(); 

     if (!string.IsNullOrEmpty(SelectedCountry)) 
     { 
      ddlCountries.SelectedValue = SelectedCountry; 

      if (!string.IsNullOrEmpty(SelectedState)) 
      { 
       ddlStates.SelectedValue = SelectedState; 
      } 
     }    
    } 


    protected override void RenderContents(HtmlTextWriter output) 
    { 
     ddlCountries.RenderControl(output); 
     ddlStates.RenderControl(output); 
    } 

    private IList<Country> GetCountryList() 
    { 
     //return stuff 
    } 

    private IList<State> GetStateList(Country country) 
    { 
     //return stuff 
    } 

    private IList<State> GetStateList(string countryAbbrev) 
    { 
     Country country = GetCountryByShortName(countryAbbrev); 
     return GetStateList(country); 
    } 

    private Country GetCountryByShortName(string countryAbbrev) 
    { 
     IList<Country> list = dataAccess.RetrieveQuery<Country>(); 
     //return stuff 
    } 

    private IList<State> GetAllStates() 
    { 
     //return stuff 
    } 

    protected void ddlCountry_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     IList<State> states = GetStateList(GetCountryList()[((DropDownList)sender).SelectedIndex]); 
     ddlStates.DataSource = states; 
     ddlStates.DataBind(); 
    } 
} 

编辑: Viewstate位于页面上,并且页面上的其他控件正确执行回发,但不是这样。

+0

大概不能算作一个答案,但Ajax控件工具包提供你想要什么已经更新面板内:http://www.asp.net/AJAX/AjaxControlToolkit/Samples/CascadingDropDown/CascadingDropDown.aspx – Sean 2009-02-20 17:05:55

+0

是的;不过,我已经宣誓永远不会。绝对垃圾IMO;实际上,我正在为我的项目构建一个替代品,因为我们只能让CCD控制与Web服务一起工作,这有其他含义。 – 2009-02-20 17:26:40

回答

5

是否打开Viewstate?

编辑: 也许你应该重新考虑重写渲染功能

protected override void RenderContents(HtmlTextWriter output) 
    { 
     ddlCountries.RenderControl(output); 
     ddlStates.RenderControl(output); 
    } 

,取而代之的是dropdownlists添加到控制和渲染使用默认RenderContents控制。

编辑: 见丹尼斯我在我以前的评论提到了答案:

Controls.Add (ddlCountries); 
Controls.Add (ddlStates); 
+0

这看起来很有希望。如果ViewState处于关闭状态(在下拉菜单或其父母的任何位置 - 一直到页面),则该事件不会触发。 (它应该回发,虽然...) – teedyay 2009-02-20 17:14:02

+0

Viewstate在控件所在的页面上。在这个.cs文件中是否有特定于此控件的特定项,我需要执行此操作? – 2009-02-20 17:14:49

+0

检查的一种快速方法是查看源代码并查看是否有任何内容存储在视图状态 – 2009-02-20 17:16:27

3

您需要设置AutoPostBack为true国家DropDownList

protected override void OnLoad(EventArgs e) 
{ 
    // base stuff 

    ddlCountries.AutoPostBack = true; 

    // other stuff 
} 

编辑

我错过了你已经做到了这一点。在这种情况下,您需要检查是否启用了ViewState。

0

首先,我想澄清一些事情。这是回发(返回服务器)永不发生,还是后回发生,但它永远不会进入ddlCountry_SelectedIndexChanged事件处理程序?

我不确定你有哪种情况,但如果是第二种情况,我可以提供一些建议。如果是第一种情况,那么以下是FYI。

对于第二种情况(事件处理程序永远不会触发即使要求订做),你可能会想尝试以下建议:

  1. 查询的Request.Params [ddlCountries.UniqueID],看看它是否具有价值。如果有,请手动触发事件处理程序。
  2. 只要视图状态为打开状态,只有列表数据不是回发时才绑定列表数据。
  3. 如果视图状态必须关闭,那么将列表数据绑定到OnInit而不是OnLoad。

请注意,在调用Control.DataBind()时,控件将不再提供查看状态和回发信息。在视图状态打开的情况下,在回发之间,DropDownList的值将保持不变(列表不会被反弹)。如果您在OnLoad中发出另一个DataBind,它将清除其视图状态数据,并且SelectedIndexChanged事件永远不会被触发。

在视图状态被关闭的情况下,你别无选择,只能重新列表每次。发生回发时,会有内部ASP.NET调用将Request.Params中的值填充到适当的控件,并且我怀疑在OnInit和OnLoad之间发生了这种情况。在这种情况下,恢复OnInit中的列表值将使系统能够正确触发事件。

感谢您的阅读时间,并欢迎大家纠正,如果我错了。

4

我看不到您要将这些控件添加到控件层次结构中。 尝试:

Controls.Add (ddlCountries); 
Controls.Add (ddlStates); 

事件将不会被调用,除非控制是控制层次结构的一部分。

1

我有同样的问题,但通过设置AutoPostBack为true并在更新面板中将触发器设置为dropdownlist控件ID和事件名称为SelectedIndexChanged,例如

<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Always" enableViewState="true"> 
     <Triggers> 
      <asp:AsyncPostBackTrigger ControlID="ddl1" EventName="SelectedIndexChanged" /> 
     </Triggers> 
     <ContentTemplate> 
      <asp:DropDownList ID="ddl1" runat="server" ClientIDMode="Static" OnSelectedIndexChanged="ddl1_SelectedIndexChanged" AutoPostBack="true" ViewStateMode="Enabled"> 
       <asp:ListItem Text="--Please select a item--" Value="0" /> 
      </asp:DropDownList> 
     </ContentTemplate> 
    </asp:UpdatePanel> 
相关问题