none
Updatepanel dropdownlist selectedindexchanged

    Pregunta

  • Tengo 4 dropdownlist que se conectan a base de datos y que al cambiar la seleccione de uno cambia el segundo y al cambiar el segundo cambio el tercero, al cambiar el tercero cambia el cuarto, ademas tengo un gridview.
    He tratado de ponerle a cada uno un updatepanel para evitar la recarga de toda la pagina, pero no me funciona, quisiera saber si alguien me podria dar una ayuda o sugerencia.
    Enrique
    sábado, 02 de mayo de 2009 1:53

Respuestas

  • Hola Enrique.

    El update panel ha sido uno de mis quebraderos de cabeza. Te explico un poco y te pongo un código de ejemplo.

    En primer lugar si usas dropDownList, debes establecer la propiedad AutoPostBack=’true’  ya que si no, no generara el evento automáticamente al cambiar de ítem.

    No sé como haces uso del update panel pero te pongo una de las formas que yo uso para estos casos. (Que mejor que un código de ejemplo)

    Pagina aspx:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title></title>
    </head>
    <body>
       
        <form id="form1" runat="server">                  
        <asp:ScriptManager runat="server" ID="scripmanager1"></asp:ScriptManager>                
        
        <div><h1>prueba de refresco de elementos en la pagina</h1></div> 
        
        <!-- primer dropdownlist con el update panel -->
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true"
                    onselectedindexchanged="DropDownList1_SelectedIndexChanged">
                    <asp:ListItem Text="numero 1"></asp:ListItem>
                    <asp:ListItem Text="numero 2"></asp:ListItem>
                    <asp:ListItem Text="numero 3"></asp:ListItem>
                </asp:DropDownList>
            </ContentTemplate>
    
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="DropDownList1" EventName="selectedindexchanged" />
            </Triggers>
        </asp:UpdatePanel>
            
        <!-- segundo dropdownlist con el update panel -->    
        <asp:UpdatePanel ID="UpdatePanel2" runat="server">
            <ContentTemplate>
                <asp:DropDownList ID="DropDownList2" runat="server" AutoPostBack="true" 
                    onselectedindexchanged="DropDownList2_SelectedIndexChanged">
                </asp:DropDownList>
            </ContentTemplate>
            
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="DropDownList2" EventName="selectedindexchanged" />
            </Triggers>
        </asp:UpdatePanel>
                 
        <!-- tercer dropdownlist con el update panel (este ya no refresca nada y no tiene trigger) -->         
        <asp:UpdatePanel ID="UpdatePanel3" runat="server">
            <ContentTemplate>        
                <asp:DropDownList ID="DropDownList3" runat="server">
                </asp:DropDownList>            
            </ContentTemplate>
        </asp:UpdatePanel>
        
        
    
        </form>
    </body>
    </html>
    

    Página c#:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace WebApplication1
    {
        public partial class _Default : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
            }
    
            protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
            {
                DropDownList2.Items.Clear();
                DropDownList2.Items.Add("numero 1");
                DropDownList2.Items.Add("numero 2");
                DropDownList2.Items.Add("numero 3");
            }
    
            protected void DropDownList2_SelectedIndexChanged(object sender, EventArgs e)
            {
                DropDownList3.Items.Clear();
                DropDownList3.Items.Add("numero 1");
                DropDownList3.Items.Add("numero 2");
                DropDownList3.Items.Add("numero 3");
            }
        }
    }
    

     

    En este ejemplo existen 3 DropDownList contenidos en un update panel y cada uno tiene su trigger que hace cambiar al siguiente, existen múltiples formas de hacer esto, yo he usado triggers para lanzar los eventos. Se puede optimizar más el código pero es un ejemplo para que practiques y saques tus conclusiones para adaptarlo a tu código.

    Espero te sirva de ayuda, si necesitas algún comentario sobre el código no dudes en pedirlo.

    Saludos.

     

    sábado, 02 de mayo de 2009 12:03

Todas las respuestas

  •  Hola Enrique,

       Si te bajas el Ajax Control Toolkit, trae un control para hacer lo que necesitas. Lo podes ver funcionando aca:
            http://www.asp.net/AJAX/AjaxControlToolkit/Samples/CascadingDropDown/CascadingDropDown.aspx
      
       El toolkit te lo podes bajar dea aca: http://ajaxcontroltoolkit.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=16488

       Espero te ayude.
       Saludos,
    Sandro D. Garcia
    Colabora con el foro: Si este mensaje te es de utilidad marcalo como respuesta.
    sábado, 02 de mayo de 2009 3:40
  • Si he visto el cascadingdropdown, pero el problema es que no he encontrado como conectar el cascadingdropdown a base de datos, tan solo he visto ejemplos con elementos estaticos o webservices, ademas tambien se actualiza el gridview y todo ello queria hacerlo de forma de actualizacion parcial, es decir que no se cargue toda la pagina por completo.

    Enrique
    sábado, 02 de mayo de 2009 5:08
  • Hola Enrique.

    El update panel ha sido uno de mis quebraderos de cabeza. Te explico un poco y te pongo un código de ejemplo.

    En primer lugar si usas dropDownList, debes establecer la propiedad AutoPostBack=’true’  ya que si no, no generara el evento automáticamente al cambiar de ítem.

    No sé como haces uso del update panel pero te pongo una de las formas que yo uso para estos casos. (Que mejor que un código de ejemplo)

    Pagina aspx:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
        <title></title>
    </head>
    <body>
       
        <form id="form1" runat="server">                  
        <asp:ScriptManager runat="server" ID="scripmanager1"></asp:ScriptManager>                
        
        <div><h1>prueba de refresco de elementos en la pagina</h1></div> 
        
        <!-- primer dropdownlist con el update panel -->
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true"
                    onselectedindexchanged="DropDownList1_SelectedIndexChanged">
                    <asp:ListItem Text="numero 1"></asp:ListItem>
                    <asp:ListItem Text="numero 2"></asp:ListItem>
                    <asp:ListItem Text="numero 3"></asp:ListItem>
                </asp:DropDownList>
            </ContentTemplate>
    
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="DropDownList1" EventName="selectedindexchanged" />
            </Triggers>
        </asp:UpdatePanel>
            
        <!-- segundo dropdownlist con el update panel -->    
        <asp:UpdatePanel ID="UpdatePanel2" runat="server">
            <ContentTemplate>
                <asp:DropDownList ID="DropDownList2" runat="server" AutoPostBack="true" 
                    onselectedindexchanged="DropDownList2_SelectedIndexChanged">
                </asp:DropDownList>
            </ContentTemplate>
            
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="DropDownList2" EventName="selectedindexchanged" />
            </Triggers>
        </asp:UpdatePanel>
                 
        <!-- tercer dropdownlist con el update panel (este ya no refresca nada y no tiene trigger) -->         
        <asp:UpdatePanel ID="UpdatePanel3" runat="server">
            <ContentTemplate>        
                <asp:DropDownList ID="DropDownList3" runat="server">
                </asp:DropDownList>            
            </ContentTemplate>
        </asp:UpdatePanel>
        
        
    
        </form>
    </body>
    </html>
    

    Página c#:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace WebApplication1
    {
        public partial class _Default : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
            }
    
            protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
            {
                DropDownList2.Items.Clear();
                DropDownList2.Items.Add("numero 1");
                DropDownList2.Items.Add("numero 2");
                DropDownList2.Items.Add("numero 3");
            }
    
            protected void DropDownList2_SelectedIndexChanged(object sender, EventArgs e)
            {
                DropDownList3.Items.Clear();
                DropDownList3.Items.Add("numero 1");
                DropDownList3.Items.Add("numero 2");
                DropDownList3.Items.Add("numero 3");
            }
        }
    }
    

     

    En este ejemplo existen 3 DropDownList contenidos en un update panel y cada uno tiene su trigger que hace cambiar al siguiente, existen múltiples formas de hacer esto, yo he usado triggers para lanzar los eventos. Se puede optimizar más el código pero es un ejemplo para que practiques y saques tus conclusiones para adaptarlo a tu código.

    Espero te sirva de ayuda, si necesitas algún comentario sobre el código no dudes en pedirlo.

    Saludos.

     

    sábado, 02 de mayo de 2009 12:03
  • Enrique es cierto uqe el cascading tenes que hacer un webservice que le pase los datos y cumplir con algunas restricciones en el nombre y parametros de los métodos. Pero se puede hacer y funciona perfectamente. Yo lo he usado algunas veces. No tengo ningún ejemplo ahora para pasarte, pero funciona muy bien y creeme que es mucho más sencillo de lo que parece. Si agarras el código del AJAX control toolkit y lo revisas, vas a ver que sencillo que es.

    Sandro D. Garcia
    Colabora con el foro: Si este mensaje te es de utilidad marcalo como respuesta.
    lunes, 04 de mayo de 2009 19:51
  • Gracias David, ya lo probe el codigo que me has puesto y si me refresca parcialmente la pagina, lo que si tenia duda con respecto al gridview pues aparte de actualizar los otros dropdownlist queria que el gridview tambien se actualice por cada seleccion de alguno de los dropdownlist con refrescamiento parcial de la pagina es decir sin hacer postback.

    Enrique
    lunes, 04 de mayo de 2009 21:54
  • ¿Pero no te sale lo del gridView?.

    ¿puedes poner el codigo de refresco del gridView, haber como lo haces?
    Saludos David González
    martes, 05 de mayo de 2009 10:51
  • Hola David, he hecho como me dijiste y me hacia un postback, bueno este es el codigo que le puse al gridview:
    <asp:UpdatePanel ID="UpdatePanel5" runat="server">
            <ContentTemplate>
                <anthem:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
                    <Columns>
                        <asp:BoundField DataField="Col1" HeaderText="Col1" />
                        <asp:BoundField DataField="Col2" HeaderText="Col2" />
                        <asp:BoundField DataField="Col3" HeaderText="Col3" />
                        <asp:BoundField DataField="Col4" HeaderText="Col4" />
                        <asp:BoundField DataField="Col5" HeaderText="Col5" />
                        <asp:BoundField DataField="Col6" HeaderText="Col6" />
                    </Columns>
                </anthem:GridView>
            </ContentTemplate>
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="GridView1" EventName="PageIndexChanged" />
                <asp:AsyncPostBackTrigger ControlID="GridView1" EventName="DataBinding" />
            </Triggers>
        </asp:UpdatePanel>
    Lo estoy conectando a una base de datos Oracle y me sale un pequeño postback tanto en el gridview como en los dropdownlist, nose si haya algo especial cuando se haga uso de base de datos que lo diferencie cuando se ponen elementos estaticos como en el ejemplo que me has dado David.
    Bueno no estaba muy seguro de que triggers ponerle por lo que le puse esos dos pues el primero era para cambiar el indice de pagina y el segundo no sabia si ponerlo cada vez que se recargue el gridview.
     

    Enrique
    martes, 05 de mayo de 2009 15:28
  • Hola de nuevo.

    He realizado pruebas y como se suele decir "a mi me funciona" :).

    Bien, te voy a poner el codigo que yo he realizado:

    aspx:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head id="Head1" runat="server">
        <title></title>
    </head>
    <body>
       
        <form id="form1" runat="server">                  
        <asp:ScriptManager runat="server" ID="scripmanager1"></asp:ScriptManager>                
        
        <div><h1>prueba de refresco de elementos en la pagina</h1></div> 
        
        <!-- primer dropdownlist con el update panel -->
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true"
                    onselectedindexchanged="DropDownList1_SelectedIndexChanged">
                    <asp:ListItem Text="numero 1"></asp:ListItem>
                    <asp:ListItem Text="numero 2"></asp:ListItem>
                    <asp:ListItem Text="numero 3"></asp:ListItem>
                </asp:DropDownList>
            </ContentTemplate>
    
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="DropDownList1" EventName="selectedindexchanged" />
            </Triggers>
        </asp:UpdatePanel>
            
        <!-- segundo dropdownlist con el update panel -->    
        <asp:UpdatePanel ID="UpdatePanel2" runat="server">
            <ContentTemplate>
                <asp:DropDownList ID="DropDownList2" runat="server" AutoPostBack="true" 
                    onselectedindexchanged="DropDownList2_SelectedIndexChanged">
                </asp:DropDownList>
            </ContentTemplate>
            
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="DropDownList2" EventName="selectedindexchanged" />
            </Triggers>
        </asp:UpdatePanel>
                 
        <!-- tercer dropdownlist con el update panel (este ya no refresca nada y no tiene trigger) -->         
        <asp:UpdatePanel ID="UpdatePanel3" runat="server">
            <ContentTemplate>        
                <asp:DropDownList ID="DropDownList3" runat="server">
                </asp:DropDownList>            
            </ContentTemplate>
        </asp:UpdatePanel>
        
        <!-- insertar un grid View para refrescarlo mediante ajax -->
        <asp:UpdatePanel ID="UpdatePanel5" runat="server">
            <ContentTemplate>    
                <asp:GridView ID="GridView1" runat="server" AllowPaging="True">                      
                    <Columns>
                        <asp:BoundField DataField="empcodigo" HeaderText="Col1" />
                        <asp:BoundField DataField="fecha" HeaderText="Col2" />
                        <asp:BoundField DataField="asunto" HeaderText="Col3" />
                    </Columns>            
                </asp:GridView>        
           </ContentTemplate>  
                         
        </asp:UpdatePanel>
    
        </form>
    </body>
    </html>
    


    cs:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Data;
    using System.Data.SqlClient;
    
    namespace WebApplication1
    {
        public partial class _Default : System.Web.UI.Page
        {
            /** Conexion con la BD */
            private SqlConnection m_connection;
            /** Enlace con la DB */
            private SqlDataAdapter m_adapter;
            /** CommandBuilder para encapsular enlace a DB */
            private SqlCommandBuilder m_builder;
            /** credenciales de autentificacion */
            private string m_credentials;
    
            protected void Page_Load(object sender, EventArgs e)
            {
                // Inicializar variables
                m_connection = new SqlConnection();
                m_adapter = new SqlDataAdapter();
                m_builder = new SqlCommandBuilder(m_adapter);
    
                // obtener datos iniciaes de la BD
                getRegisters(@"consulta de prueba");
            }
    
            protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
            {
                DropDownList2.Items.Clear();
                DropDownList2.Items.Add("numero 1");
                DropDownList2.Items.Add("numero 2");
                DropDownList2.Items.Add("numero 3");
    
            }
    
            protected void DropDownList2_SelectedIndexChanged(object sender, EventArgs e)
            {
                DropDownList3.Items.Clear();
                DropDownList3.Items.Add("numero 1");
                DropDownList3.Items.Add("numero 2");
                DropDownList3.Items.Add("numero 3");
    
                // obtener datos de la BD
                getRegisters(@"consulta de prueba");
            }
    
            /// <summary>
            /// Obtiene todos los registros de la tabla seleccionada y los muestra en el DataGrid
            /// </summary>   
            private void getRegisters(string query)
            {
                //Declaración de variables requeridas
                SqlCommand SQLcmd = new SqlCommand();
                DataTable table = new DataTable();
    
                // Establecer la conexion con la BD especifida
                m_connection.ConnectionString = "Cadena de conexion a la BD";
    
                //Asignación de propiedades
                SQLcmd.Connection = m_connection;
                SQLcmd.CommandType = CommandType.Text;
                // La consulta se forma
                SQLcmd.CommandText = query;
    
                // Ejecutar la consulta
                m_adapter.SelectCommand = SQLcmd;
    
                //Intento de llenado de datos hacia la variable dt DataTable
                try
                {
                    m_adapter.Fill(table);
                }
                catch (SqlException ex)
                {
                    Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "ErrorSQL",
                        "<script type=\"text/javascript\">alert('" + ex.Message + "');</script>");
                }
                catch (Exception ex)
                {
                    Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "ErrorSQL",
                        "<script type=\"text/javascript\">alert('" + ex.Message + "');</script>");
                }
    
                // Relacionar los datos del datagrid.
                GridView1.DataSource = table;
                GridView1.DataBind();
    
            }
        }
    }
    
    


    Si te fijas, realmente una funcion, llamada mediante un trigger de un update panel, solo puede modificar contenido dentro de un updatepanel.
    En este ejemplo, yo he usado BD sql server. Como puedes comprobar al cambiar cualquier elemento del combo2, este llama a su funcion selectedIndexChanged donde genero otra consulta que refrescara el grid, el grid es refrescado sin volver a cargar la pagina.

    Realmente, cualquier control que este dentro del updatePanel se puede refrescar mediante un evento de postBack asincrono como por ejemplo los triggers.
    Prueba esto ultimo y comentas como te a ido.


    Saludos David González
    miércoles, 06 de mayo de 2009 8:23
  • Holas nuevamente:
    Bueno David mi pregunta era más con respecto a los dropdownlist que se conecten a base de datos, si deba configurarse un trigger adicional o nomas es suficiente con el trigger de SelectedIndexChanged pues como te dije en un comentario anterior a mi sale un postback de la pagina y lo que yo quisiera es que no haga un postback de la pagina sino que me haga solamente una actualizacion parcial de la pagina, la conexion de base de datos, paso de parametros y databind de los dropdownlist los hago dentro del mismo evento selectedindexchanged de cada uno de los dropdownlist, Por lo del gridview gracias por el dato ahora ya se que nomas necesitaria el trigger para el pageindexchanged.

    Saludos Enrique Diaz.
    Enrique
    jueves, 07 de mayo de 2009 22:37
  • Que tal Enrique.

    En un principio el evento es lo de menos, puedes usar el evento que quieras, cuando se lanze el trigger ira a la funcion especificada y desde esa funcion se puede refrescar cualquier elemento contido dentro de un updatePanel (ojo, solo se pueden refrescar elementos que esten dentro de cualquier update panel, elementos que no esten dentro de un updatepanel haran caso omiso).

    De todas formas si puedes pasar el codigo aspx y cs le puedo echar un vistazo haber por que no te funciona, yo he realizado pruebas con oracle y van perfectamente, en un principio la BD no tiene nada que ver, ya que El updatePanel hace una llamada asincrona al servidor con el objeto XMLHttpRequest que es el pilar de la funcionalidad de AJAX, el servidor procesa la funcion y cuando la retorna avisa al objeto XMLHttpRequest con un estatus ok, donde mediante javascript se actualiza la capa designada. Debido a que la operacion es asincrona, se puede llamar perfectamente a cualquier BD.

    No obstante hay veces que un pequeño fallo en el codigo o un parseado mal hace que no funcione el sistema, por ejemplo a mi me fallo una vez por un tag de cierre en la pagina, asegurate de que la pagina pasa la especificacion establecida en la cabecera y no use el modo QUIRKS el navegador.


    Saludos David González
    viernes, 08 de mayo de 2009 6:22