11

Tôi đang tạo một điều khiển máy chủ về cơ bản liên kết hai danh sách thả xuống, một cho quốc gia và một cho tiểu bang, và cập nhật trạng thái thả xuống sự kiện selectedindexchanged của đất nước. Tuy nhiên, nó không đăng lại. Bất kỳ ý tưởng tại sao? điểm thưởng cho gói chúng trong một UpdatePanel (có vấn đề render, có lẽ bởi vì tôi không có một trang để tham khảo?)ASP.NET/C#: DropDownList SelectedIndexChanged trong điều khiển máy chủ không kích hoạt

Dưới đây là những gì tôi có (với một số công cụ bổ sung truy cập dữ liệu tước ra):

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

Chỉnh sửa: Chế độ xem đang ở trên trang và các điều khiển khác trên trang thực hiện đăng lại chính xác, không phải điều này.

+0

lẽ không được tính là một câu trả lời nhưng Ajax Control Toolkit cung cấp những gì bạn muốn đã được bên trong một bảng cập nhật: http://www.asp.net/AJAX/AjaxControlToolkit/Samples/CascadingDropDown/CascadingDropDown.aspx – Sean

+0

Có; Mặc dù vậy, tôi đã tuyên thệ nhậm chức ACT mãi mãi. IMO rác tuyệt đối; Tôi đang thực sự xây dựng một sự thay thế cho dự án của tôi, vì chúng tôi chỉ có thể có được sự kiểm soát CCD để làm việc với một dịch vụ web, có những tác động khác. –

Trả lời

5

Chế độ ViewState có được bật không?

Edit: Có lẽ bạn nên xem xét lại trọng chức năng vẽ

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

và thay vào đó thêm dropdownlists để kiểm soát và đưa ra thị bằng biểu tượng RenderContents mặc định.

Edit: Xem câu trả lời từ Dennis mà tôi nhắc đến trong bình luận trước đây của tôi:

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

Điều này có vẻ đầy hứa hẹn. Nếu ViewState bị tắt (trên menu thả xuống hoặc bất kỳ bố mẹ nào của nó - tất cả các cách lên đến trang) thì sự kiện sẽ không kích hoạt. (Nó nên đăng trở lại mặc dù ...) – teedyay

+0

Viewstate nằm trên trang mà bộ điều khiển nằm trên đó. Có một cái gì đó cụ thể để kiểm soát này, trong tập tin này .cs, mà tôi cần phải làm gì? –

+0

một cách nhanh chóng để kiểm tra là xem mã nguồn và xem liệu có bất kỳ điều gì được lưu trữ trong viewstate –

3

Bạn cần phải thiết lập AutoPostBack đến đúng đối với Country DropDownList.

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

    ddlCountries.AutoPostBack = true; 

    // other stuff 
} 

Sửa

tôi bị mất mà bạn đã làm điều này. Trong trường hợp đó, bạn cần kiểm tra xem ViewState có được kích hoạt hay không.

+0

Dòng của anh ấy "ddlCountries.AutoPostBack = true;" không làm điều này? –

0

Trước tiên, tôi muốn làm rõ điều gì đó. Đây có phải là một bài trở lại (chuyến đi trở lại máy chủ) không bao giờ xảy ra, hoặc là nó đăng lại xảy ra, nhưng nó không bao giờ được vào xử lý sự kiện ddlCountry_SelectedIndexChanged?

Tôi không chắc bạn đang gặp trường hợp nào, nhưng nếu đây là trường hợp thứ hai, tôi có thể đưa ra một số gợi ý. Nếu đó là trường hợp đầu tiên, thì sau đây là FYI.

Đối với trường hợp thứ hai (xử lý sự kiện không bao giờ cháy mặc dù yêu cầu thực hiện), bạn có thể muốn thử những gợi ý sau đây:

  1. Query các Request.Params [ddlCountries.UniqueID] và xem nếu nó có giá trị . Nếu có, hãy kích hoạt trình xử lý sự kiện theo cách thủ công.
  2. Khi trạng thái xem được bật, chỉ ràng buộc dữ liệu danh sách khi nó không phải là bài đăng.
  3. Nếu trạng thái xem bị tắt, hãy đặt dữ liệu danh sách liên kết trong OnInit thay vì OnLoad.

Hãy cẩn thận khi gọi đến Control.DataBind(), trạng thái xem và thông tin đăng lại sẽ không còn khả dụng từ điều khiển nữa. Trong trường hợp trạng thái xem được bật, giữa bài đăng trở lại, các giá trị của DropDownList sẽ được giữ nguyên (danh sách không được phục hồi). Nếu bạn phát hành một DataBind khác trong OnLoad, nó sẽ xóa dữ liệu trạng thái xem của nó và sự kiện SelectedIndexChanged sẽ không bao giờ bị sa thải.

Trong trường hợp trạng thái chế độ xem bị tắt, bạn không có lựa chọn nào khác ngoài việc phải rebind danh sách mỗi lần. Khi một bài đăng trở lại xảy ra, có các cuộc gọi ASP.NET nội bộ để điền giá trị từ Request.Params vào các điều khiển thích hợp và tôi nghi ngờ xảy ra tại thời điểm giữa OnInit và OnLoad. Trong trường hợp này, việc khôi phục các giá trị danh sách trong OnInit sẽ cho phép hệ thống kích hoạt các sự kiện một cách chính xác.

Cảm ơn bạn đã dành thời gian đọc sách này và chào mừng mọi người sửa nếu tôi sai.

+0

Nó hoàn toàn không ảnh hưởng đến máy chủ khi tôi thay đổi mục danh sách đã chọn. Cảm ơn, mặc dù; đó là một vấn đề khác mà tôi phải khắc phục ở các khu vực khác và đó là thông tin tốt. –

+0

Tôi thấy; sau đó tôi nghĩ câu trả lời từ Dennis Myren có thể là chính xác: hai DropDownList không nằm trong cây điều khiển, vì vậy mặc dù chúng được kết xuất chính xác, cơ chế xử lý sự kiện ASP.NET đơn giản là không thể nhìn thấy sự tồn tại từ cấp độ Trang không có sự kiện nào bị sa thải. –

4

Tôi không thể thấy rằng bạn đang thêm các điều khiển này vào hệ thống phân cấp điều khiển. Thử:

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

Sự kiện sẽ không được gọi trừ khi điều khiển là một phần của hệ thống phân cấp kiểm soát.

+0

Có - và thực hiện việc này trong một sự kiện sớm hơn Tải (chẳng hạn như Init); nếu không các điều khiển sẽ không ở đúng nơi khi ViewState được tải lại. – teedyay

+0

Vâng, hoặc tốt nhất là ghi đè lên CreateChildControls – baretta

+0

Đã định nói cùng một điều ... chúng sẽ được tạo và thêm vào bộ sưu tập Điều khiển trong CreateChildControls. Bạn cũng có thể hủy ghi đè Render. – flatline

1

Tôi đã gặp sự cố tương tự nhưng đã làm tròn nó bằng cách đặt Tự động sao lưu thành true và trong bảng điều khiển cập nhật đặt trình kích hoạt thành id điều khiển danh sách thả xuống và tên sự kiện thành SelectedIndexChanged ví dụ:

<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> 
Các vấn đề liên quan