11

Estoy creando un control de servidor que básicamente vincula dos listas desplegables, una para el país y otra para el estado, y actualiza el menú desplegable del estado en el evento indexado seleccionado del país. Sin embargo, no se está publicando. ¿Alguna idea de por qué? Los puntos de bonificación para envolviéndolos en un UpdatePanel (que tienen problemas de representación, tal vez porque no tiene una página para hacer referencia?)ASP.NET/C#: DropDownList SelectedIndexChanged en el control del servidor no activa

Aquí es lo que tengo (con un poco de materia de acceso a datos adicional quitó):

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

Editar: Viewstate está en la página, y otros controles en la página realizan devoluciones de datos correctamente, simplemente esto no.

+0

Probablemente no cuenta como una respuesta, pero el Ajax Control Toolkit proporciona lo que ya quiere dentro de un panel de actualización: http://www.asp.net/AJAX/AjaxControlToolkit/Samples/CascadingDropDown/CascadingDropDown.aspx – Sean

+0

Sí; Sin embargo, he renunciado al ACT para siempre. Absoluta basura IMO; De hecho, estoy creando un reemplazo para mi proyecto, ya que solo podíamos lograr que el control CCD funcionara con un servicio web, lo que tenía otras implicaciones. –

Respuesta

5

¿Está encendido Viewstate?

Editar: tal vez debería reconsiderar anulando la función de representación

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

y en lugar de añadir los dropdownlists al control y representar el control usando los RenderContents por defecto.

Editar: ver la respuesta de Dennis, que he aludido en mi comentario anterior:

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

Esto parece prometedor. Si ViewState está desactivado (en el menú desplegable o cualquiera de sus padres, hasta el final de la página), el evento no se activará. (Debería publicarlo ...) – teedyay

+0

Viewstate está activado en la página donde reside el control. ¿Hay algo específico para este control, en este archivo .cs, que deba hacer? –

+0

una manera rápida de verificar es mirar el código fuente y ver si hay algo almacenado en viewstate –

3

Es necesario establecer AutoPostBack a cierto para el País DropDownList.

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

    ddlCountries.AutoPostBack = true; 

    // other stuff 
} 

Editar

que se perdió que había hecho esto. En ese caso, debe verificar que ViewState esté habilitado.

+0

Hace su línea "ddlCountries.AutoPostBack = true;" no hacer esto? –

0

En primer lugar, me gustaría aclarar algo. ¿No es esto una publicación posterior (viaje de regreso al servidor) que nunca ocurre, o es la publicación posterior, pero nunca entra en el controlador de eventos ddlCountry_SelectedIndexChanged?

No estoy seguro de qué caso está teniendo, pero si es el segundo caso, puedo ofrecer alguna sugerencia. Si es el primer caso, entonces lo siguiente es FYI.

Para el segundo caso (controlador de eventos nunca se disparará, a pesar de que la solicitud hecha), es posible que desee probar las siguientes sugerencias:

  1. consulta las Request.Params [ddlCountries.UniqueID] y ver si tiene valor . Si lo tiene, ejecute manualmente el controlador de eventos.
  2. Mientras el estado de vista esté activado, solo vincula los datos de la lista cuando no se trate de una publicación posterior.
  3. Si el estado de la vista tiene que estar desactivado, coloque los datos de la lista vinculados en OnInit en lugar de OnLoad.

Tenga en cuenta que al llamar Control.DataBind(), ver estado y publicar información ya no estaría disponible desde el control. En el caso de que el estado de vista esté activado, entre la publicación posterior, los valores de DropDownList se mantendrían intactos (la lista no se recuperará). Si emite otro DataBind en OnLoad, borrará sus datos de estado de vista, y el evento SelectedIndexChanged nunca se disparará.

En el caso de que el estado de la vista esté desactivado, no tiene más remedio que volver a enlazar la lista cada vez. Cuando se produce una publicación posterior, hay llamadas ASP.NET internas para completar el valor de Request.Params a los controles apropiados, y sospecho que suceden en ese momento entre OnInit y OnLoad. En este caso, al restaurar los valores de la lista en OnInit, el sistema activará los eventos correctamente.

Gracias por su tiempo leyendo esto, y les doy la bienvenida a todos a corregir si me equivoco.

+0

No está llegando al servidor en absoluto cuando cambio el elemento de la lista seleccionada. Gracias, sin embargo; ese es otro problema que he tenido que solucionar en otras áreas y es buena información. –

+0

Veo; entonces creo que la respuesta de Dennis Myren probablemente sea la correcta: los dos DropDownList no están en el árbol de control, por lo tanto, aunque se procesen correctamente, los mecanismos de manejo de eventos ASP.NET simplemente no pudieron ver la existencia desde el nivel de página, por lo tanto ningún evento se dispara. –

4

No veo que agregue estos controles a la jerarquía de control. Probar:

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

Los eventos no se invocarán a menos que el control es parte de la jerarquía de control.

+0

Sí, y haga esto en un evento anterior a la Carga (como el Init); de lo contrario, los controles no estarán en el lugar correcto cuando ViewState se vuelva a cargar. – teedyay

+0

Sí, o preferiblemente al reemplazar CreateChildControls – baretta

+0

Estuvo a punto de decir lo mismo ... deberían crearse y agregarse a la colección Controls en CreateChildControls. Puede soltar la anulación de Render también. – flatline

1

Tuve el mismo problema pero lo solucioné configurando AutoPostBack en verdadero y en un panel de actualización configuré el desencadenador para el identificador de control de lista desplegable y el nombre del evento en SelectedIndexChanged, p.

<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> 
Cuestiones relacionadas