11

Tworzę kontrolę serwera, która w zasadzie wiąże dwie listy rozwijane, jedną dla kraju i jedną dla stanu, i aktualizuje listę rozwijaną stanu w wybranym kraju wydarzenie zindeksowane. Jednak nie jest wysyłane z powrotem. Jakieś pomysły, dlaczego? Dodatkowe punkty za owijanie ich w UpdatePanel (problemy renderingu; może dlatego nie mam strony do odniesienia?)ASP.NET/C#: DropDownList SelectedIndexChanged w kontrolerze serwera nie uruchamiając

Oto co mam (z jakiś dodatkowy dostęp do danych rzeczy pozbawione out):

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

Edytuj: Stan widoku jest na stronie, a inne elementy sterujące na stronie wykonują poprawnie zwroty, ale nie to.

+0

Prawdopodobnie nie liczy się jako odpowiedź ale Ajax sterowania Toolkit zapewnia co już chcą wewnątrz panelu aktualizacji: http://www.asp.net/AJAX/AjaxControlToolkit/Samples/CascadingDropDown/CascadingDropDown.aspx – Sean

+0

Tak; Przysięgałem jednak na ACT na zawsze. Absolutne śmieci IMO; Naprawdę buduję zamiennik dla mojego projektu, ponieważ mogliśmy uzyskać kontrolę nad CCD tylko przy pomocy usługi sieciowej, co miało inne implikacje. –

Odpowiedz

5

Czy Viewstate jest włączony?

Edit: Być może należy rozważyć przesłanianie funkcja renderowania

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

i zamiast dodawać dropdownlists do kontroli i doprowadzić do kontroli przy użyciu domyślnych RenderContents.

Edit: Zobacz odpowiedź od Dennis których wspomniałem w moim poprzednim komentarzu:

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

To wygląda obiecująco. Jeśli funkcja ViewState jest wyłączona (na liście rozwijanej lub którejkolwiek z jej rodziców - aż do strony), wydarzenie się nie uruchomi. (Powinien jednak wysłać z powrotem ...) – teedyay

+0

Viewstate jest włączone na stronie, na której znajduje się formant. Czy jest coś szczególnego dla tej kontroli w tym pliku .cs, które muszę zrobić? –

+0

szybki sposób sprawdzenia polega na sprawdzeniu kodu źródłowego i sprawdzeniu, czy coś jest przechowywane w stanie widoku –

3

Musisz ustawić AutoPostBack true dla kraju DropDownList.

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

    ddlCountries.AutoPostBack = true; 

    // other stuff 
} 

Edit

brakowało mi, że to zrobił. W takim przypadku musisz sprawdzić, czy funkcja ViewState jest włączona.

+0

Czy jego wiersz "ddlCountries.AutoPostBack = true;" nie robisz tego? –

0

Po pierwsze, chciałbym coś wyjaśnić. Czy to nie jest zwrotne (powrót do serwera) nigdy nie występuje, czy jest to cofnięcie, ale nigdy nie dostaje się do obsługi zdarzenia ddlCountry_SelectedIndexChanged?

Nie jestem pewien, który przypadek masz, ale jeśli jest to drugi przypadek, mogę zaoferować kilka sugestii. Jeśli jest to pierwszy przypadek, to jest to FYI.

W drugim przypadku (obsługi zdarzeń nigdy pożary choć wniosek złożony), może chcesz spróbować następujące propozycje:

  1. kwerendy Request.Params [ddlCountries.UniqueID] i sprawdzić, czy ma wartość . Jeśli tak, ręcznie uruchom obsługę zdarzenia.
  2. Dopóki stan widoku jest włączony, wiązać dane listy tylko wtedy, gdy nie jest ona powrotem z powrotem.
  3. Jeśli stan widoku musi być wyłączony, należy powiązać dane listy w trybie OnInit zamiast w trybie OnLoad.

Pamiętaj, że podczas wywoływania Control.DataBind(), wyświetlanie informacji o stanie i informacji zwrotnej nie będzie już dostępne z formantu. W przypadku, gdy stan widoku jest włączony, pomiędzy kolejnymi odsyłaczami wartości DropDownList pozostaną nienaruszone (lista nie będzie się odbijać). Jeśli wydasz inną funkcję DataBind w trybie OnLoad, usunie ona dane stanu widoku, a zdarzenie SelectedIndexChanged nigdy nie zostanie uruchomione.

W przypadku, gdy stan widoku jest wyłączony, nie ma innego wyjścia, jak tylko ponowne powiązanie listy za każdym razem. Kiedy następuje zwrotne zgłoszenie, są wewnętrzne wywołania ASP.NET, które zapełniają wartość z Request.Params do odpowiednich kontrolek i podejrzewam, że zdarzają się one w czasie między OnInit i OnLoad. W takim przypadku przywrócenie wartości list w OnInit umożliwi systemowi prawidłowe uruchamianie zdarzeń.

Dziękuję za poświęcony czas przeczytaniu tego i zapraszam wszystkich do poprawiania, jeśli się mylę.

+0

To wcale nie uderza w serwer, gdy zmienię wybrany element listy. W każdym razie dzięki; to jest kolejny problem, który muszę naprawić w innych obszarach i to jest dobra informacja. –

+0

Widzę; wtedy myślę, że odpowiedź od Dennisa Myrena będzie prawdopodobnie poprawna: dwie listy rozwijane DropDownList nie znajdują się w drzewie kontrolnym, więc mimo tego, że są poprawnie renderowane, mechanizmy obsługi zdarzeń ASP.NET po prostu nie mogły zobaczyć istnienia z poziomu strony, a więc żadne wydarzenie nie zostanie zwolnione. –

4

Nie widzę, że dodajesz te elementy sterujące do hierarchii kontrolnej. Spróbuj:

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

wydarzenia nie zostanie wywołana, chyba że kontrola jest częścią hierarchii sterowania.

+0

Tak - i zrób to w zdarzeniu wcześniejszym niż obciążenie (takie jak Init); w przeciwnym razie elementy sterujące nie będą we właściwym miejscu po ponownym załadowaniu obiektu ViewState. – teedyay

+0

Tak, lub najlepiej w override CreateChildControls – baretta

+0

Zamierzasz powiedzieć to samo ... powinny one zostać utworzone i dodane do kolekcji Controls w CreateChildControls. Możesz także zrezygnować z nadpisywania renderingu. – flatline

1

Miałem ten sam problem, ale obejść go, ustawiając AutoPostBack na wartość true iw panelu aktualizacji ustaw wyzwalacz na identyfikator kontrolny listy rozwijanej i nazwę zdarzenia na SelectedIndexChanged np.

<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> 
Powiązane problemy