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> 
相關問題