Introducción
El objetivo de este articulo será el de demostrar con un ejemplo completo como cargar controles que dependen de la información de toros controles para desplegar la información.
Se usara para este ejemplo tres controles DropDownList que irán filtrando en cascada, hasta llegar al una grilla final, implementada con el GridView, la cual mostrara los clientes que realizaron la compra.
Cascada de Eventos
El punto importante en el ejemplo es analizar como los eventos de los controles interactúan entre ellos.
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { LoadComboArtist(); } } protected void ddlArtist_SelectedIndexChanged(object sender, EventArgs e) { int ArtistId = Convert.ToInt32(ddlArtist.SelectedValue); LoadComboAlbum(ArtistId); } protected void ddlAlbum_SelectedIndexChanged(object sender, EventArgs e) { int AlbumId = Convert.ToInt32(ddlAlbum.SelectedValue); LoadComboTrack(AlbumId); } protected void ddlTrack_SelectedIndexChanged(object sender, EventArgs e) { int TrackId = Convert.ToInt32(ddlTrack.SelectedValue); LoadGridViewCustomer(TrackId); }
Como se observa en el código, cada evento toma el id de la entidad que representa e inmediatamente después llama a la funcionalidad que carga el combo que le precede.
private void LoadComboArtist() { ddlArtist.DataSource = ChinookDAL.GellAllArtist(); ddlArtist.DataTextField = "Name"; ddlArtist.DataValueField = "ArtistId"; ddlArtist.DataBind(); if (ddlArtist.Items.Count != 0) { int ArtistId = Convert.ToInt32(ddlArtist.SelectedValue); LoadComboAlbum(ArtistId); } else { ddlAlbum.Items.Clear(); ddlTrack.Items.Clear(); dvCustomer.DataSource = null; dvCustomer.DataBind(); } } private void LoadComboAlbum(int ArtistId) { ddlAlbum.DataSource = ChinookDAL.GellAlbumByArtist(ArtistId); ddlAlbum.DataTextField = "Title"; ddlAlbum.DataValueField = "AlbumId"; ddlAlbum.DataBind(); if (ddlAlbum.Items.Count != 0) { int AlbumId = Convert.ToInt32(ddlAlbum.SelectedValue); LoadComboTrack(AlbumId); } else { ddlTrack.Items.Clear(); dvCustomer.DataSource = null; dvCustomer.DataBind(); } } private void LoadComboTrack(int AlbumId) { ddlTrack.DataSource = ChinookDAL.GellTrackByAlbum(AlbumId); ddlTrack.DataTextField = "Name"; ddlTrack.DataValueField = "TrackId"; ddlTrack.DataBind(); if (ddlTrack.Items.Count != 0) { int TrackId = Convert.ToInt32(ddlTrack.SelectedValue); LoadGridViewCustomer(TrackId); } else { dvCustomer.DataSource = null; dvCustomer.DataBind(); } } private void LoadGridViewCustomer(int TrackId) { dvCustomer.DataSource = ChinookDAL.GellCustomerByTrack(TrackId); dvCustomer.DataBind(); }
Cada método invoca a la funcionalidad de la DAL (Data Access Layer), para recuperar la información.
Se valida que el combo tenga ítem, y en caso de tenerlos invoca la carga del control que sigue en la jerarquía de controles anidados.
En caso de no tener ítem, realiza el borrado de todos los controles que depende de este en la cascada.
Aclaraciones
La base de datos utilizada en el ejemplo fue obtenido del sitio codeplex: Chinook
Para poder ejecutar la aplicación simplemente deben tener el Sql Server Express corriendo en la PC local
[C#]
|
[VB.NET]
|
ok... hay mucho ejemplos de la misma carecteristica... como se podria hacer si no tenemos un numero fijo de DropDownList, algo que sea dimamico...
ResponderEliminarhola Norman
ResponderEliminardisculpa la tardanza en responder
El que sea dinamico no tendria tanta complicacion el tema sera a que evento de SelectedIndexChanged suscribir ese control para que informe la seleccion y cargue el siguiente combo
Quizas se podria usar unico evento al cual se atachan todos los combos dinamicos y con algun valor compuesto en el SelectedValue se indicaria cual es el proximo control a cargar.
Por supuesto la busqueda de ese control se haria tambien dinamica por medio del FindControl() en la Page
Pero igual esto es solo una idea, habria que analizarlo mejor
saludos
Hola leandro, acabo de ver tu ejemplo, y eso más o menos es lo que yo quiero hacer pero con un CascadingDrpDown, pero me da Method error 500, ¿sabrías decirme a qué se debe?
ResponderEliminarhola Angeles
ResponderEliminarBueno con el CascadingDropDown es bastante distinto de implementar, imagino has creado los servicio web que devuelven la info que carga la data de cada combo
CascadingDropDown Demonstration
Prueba de poner un breakpoint en los servicio y validar que no se generen problemas alli y se carga la info que retorna de forma correcta.
Using CascadingDropDown with a Database
saludos
Hola Leandro,
ResponderEliminarhe implementado tu codigo pero en vez de artistas, albums y tracks, lo he hecho en tipos de producto, producto y rango de producto..
lo que pasa es que al mostrar el grid con los rangos de podructo no puedo programar el evento paging changing porque no se a que función llamar y eso..
me podrías ayudar? es un poco urgente.. muchas gracias por adelantadoo!
hola Ramon
ResponderEliminarel que tengas controles anidados no deberia afectar en nada al paginado del grid
Este lo paginas comunmente, como menciono aqui
http://social.msdn.microsoft.com/Forums/es/netfxwebes/thread/714178ec-726f-46c0-805c-c7b1028669cd
veras que implementas el evento PageIndexChanging
y en este evento no solo asignas la pagina a la cual se debe ir, sino que vuelves a asignar los datos para bidnear el grid.
saludos
Hola de nuevo Leandro..
ResponderEliminarentiendo lo que quieres decir, y el funcionamiento del evento.. Lo que no sé.. es como volver a rellenar el grid..
yo tengo una función que es:
private void LoadGridViewIntervenciones(int id_cliente)
{
gvIntervenciones.DataSource = DB.GellInterventionsByCliente(id_cliente);
gvIntervenciones.DataBind();
}
y en el evento que debo poner para rellenenar?
protected void gvIntervenciones_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
int newPageNumber = e.NewPageIndex + 1;
-------
---------
}
Muchas gracias por adelantado y perdona por la ignorancia.. voy aprendiendo.. jeje
hola Ramon
ResponderEliminaralgo como esto
gvIntervenciones_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
int newPageNumber = e.NewPageIndex + 1;
LoadGridViewIntervenciones(Convert.ToInt32(txtisCliente.Text));
}
o sea tomas el id de la misma forma que lo has usado la primera vez para cargar, alli puse de ejemplo que se toma de un textbox
pero si lo tienes en un Session tambien es valido
saludos
Hola como se podria anidar los dropdownlist usando linq un ejemplo de PAIS, ESTADO, CIUDAD
ResponderEliminarhola charly
ResponderEliminarusando linq ? te refieres a linq to sql
la tecnica es la misma solo que el valor que tomas de la seleccion anterior la usas de filtro en el where de linq
var result = from item in context.Estados
where item.IdPais == cbpaises.SelectedValue
select item;
es un ejemplo por supuesto no digo que sea exatamente de esta forma pero como veras usas la seleccion como filtro
saludos
hola Leonardo, tengo una duda que hace esto:
ResponderEliminarChinookDAL.GellAllArtist();
es que intento acomodar el código con el que yo tengo y todo va bien y entiendo cada cosa solo que esa parte no se que hace ni en que parte la creaste ...
gracias : )!
hola
ResponderEliminarrealiza una busqueda en toda al solucion por el nombre ChinookDAL
deberias encontrar una clase definida como static, es alli donde esta el metodo para recuperar los artistas
esa clase pertenece a la capa de datos
saludos
Hola Leandro buenas tardes.Quisiera saber como puedo almacenar el texto que cotniene el Dropdonwlist. Espero tu respuesta. Hasta luego.
ResponderEliminarHola Leandro. Qusiera almacenar el texto que contiene el DropDownList y no el Id. Espero tu pronta respuesta. Hasta luego.
ResponderEliminarhola
ResponderEliminarlamacenarlo donde ? en una db en un archivo de texto
puedes tomar el texto del combo usando
string cadena = DropDownlist1.SeletedItem.Text;
saludos
Hola Leandro, tengo ungridview con combos anidados que se deben editar, el detalle que tengo es que cuando estoy en modo edicion y cambio el valor del primer Dropdown me envia al evento editar del gridview en lugar del evento del combo. como puedo resolverlo? de anntemano agradezco tu ayuda
ResponderEliminarhola Jessica
ResponderEliminarlo primero que podria recomendar es que no anides controles dentro de un gridview, porque es para problemas
al estar en control como contenedor de otro es logico que los eventos sean del control que los contiene, si defines la propiedad AutoPostBack = true en el dropdownlist deberias poder capturar ese evento, pero vas a necesitar tambine usar el
NamingContainer
para poder localizar el combo de que fila lanzo la accion y localizar el otro control que debes afectar
como veras se podria hacer pero no es nada directo, por eso en estos casos tienedo a editar por fuera del grid seleccionando la row y editando en controles simples
saludos
Hola Leandro yo tengo un DropDownList que la edite con los meses solamente estos no estan cargados a ninguna bd. tengo una store procedure que me gustaria desplegarla al momento de seleccionar Enero me despligue en el grid todos los datos que tengo en ese mes, el problema aqui es que no me despliga la store procedure en el grid no logro verla, y de acuerdo a unos campos are una resta de fechas que no se como desplegar en cada fila del grid ni usar los eventos que explicas. No ce si me di a enternder ojala puedas ayudarme!!
ResponderEliminarhola mElYnIt@
ResponderEliminarese procedure que dato recibe como parametro ? solo el numero del mes seleccionado en el combo o tambien un año en concreto
como pasas los parametros al procedure cuando ejecutas, usas el Parameters del SqlCommand ?
saludos
Hola Leandro
ResponderEliminarEl codigo ejemplo no lo puedo bajar, como hago? Gracias
hola Unknown
ResponderEliminarya esta actualizado para que puedas descargar el codigo
saludos
Como se hace con base de datos en sql
ResponderEliminarhola edi ska
ResponderEliminarpero alli se utiliza una base de datos sql server
lo unico es que la forma de conectarse es por medio de un attach dinamico, si la idea es usar una db dentro del servicio de sql server solo debes definir el connection string que esta en web.config para que apunte a esa db
saludos
hola leandro, tengo una pregunta,
ResponderEliminartengo una pagina en donde uso dos dropdownlist, pero no logro que al seleccionar un item del primero me actualice el segundo,
alguna sugerencia?
hola eco
ResponderEliminarasignaste la propiedad AutoPostBack en true del dropdownlist
sino lo haces el evento de seleccion no se ejecuta
saludos
Que tal Leandro.
ResponderEliminarTengo el siguiene inconveniento, tengo un ddl pero al seleccionar un elemento y hacer el autoposback me devuelve siempre al mismo.
< asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" OnTextChanged="DropDownList1_TextChanged" >
< asp:ListItem Value="1" Text="Melon">< /asp:ListItem>
< /asp:ListItem>
< asp:ListItem Value="1" Text="Durazno">< /asp:ListItem>
< asp:ListItem Value="1" Text="Pera">< /asp:ListItem>
< /asp:DropDownList>
< asp:Label ID="Label1" runat="server">< /asp:Label>
----------
protected void DropDownList1_TextChanged(object sender, EventArgs e)
{
if (DropDownList1.SelectedValue == "1")
{
Label1.Text = " Valor = " + DropDownList1.SelectedValue + " Texto = " + DropDownList1.SelectedItem.Text;
}
else
{
Label1.Text = "No se selecciono nada";
}
}
Ya le he intentado de mil formas pero no he logrado de solucionar.
hola tengo una duda, me tira error una parte del codigo que cambie para acomodarlo al mio.
ResponderEliminarprivate static Pais Cargar_Pais(IDataReader reader)
{
Pais item = new Pais();
item.id_pais = Convert.ToInt32(reader["id_pais"]);
item.pais = Convert.ToString(reader["pais"]);
return item;
}
el error me da en id_pais y me dice: No se puede convertir un objeto DBNull en otros tipos.
hola diego
ResponderEliminarcreo que esta pregunta la realizaste en el foro, pero no encontre donde
por eso repito la repsuesta, un campo que indica un id o key d ela tabla no puede permitir nulos, sino deja de ser un id
para campos nulos deberias validarlo
if(reader["id_pais"] != DBNull.Value){
item.id_pais = Convert.ToInt32(reader["id_pais"]);
}
solo asignas si el campo no tiene ningun null
saludos
hola jupemen
ResponderEliminaren que evento cargas los datos del combo, lo haces en el Page_Load?
porque si es asi recuerda que debes ponerlos dentro del
if(!IsPostBack){
//aqui cargas los datos
}
sino no pones dentro del if entonces se recargara por cada evento perdiendo la seleccion
saludos
Correcto, se carga el primer drop, sin embargo cuando seleccionas un ítem de ese, deseas que se cargue el segundo de acuerdo a tu selección del primero, pero este se reinicia y queda en el primer ítem y no hay forma, si quitas el Autopostback entonces no se activa el segundo Drop. que problema con estos drop anidados o dependientes. Sugerencias..y gracias
EliminarHola Leandro
ResponderEliminarTe queria consultar, sobre dropdownlist anidados.
Tengo un dropdownlist de inicio y 3 dropdownlist mas encadenados.
Al momento de modificar los datos, rescato los valores para mostrar en pantalla y el primer combo que no tiene filtro, muestra bien, en cambio los dependientes no muestra debido a que no encuentra el valor.
Probe haciendo databind al dataset y al dropdownlist y no me arroja error, pero no muestra elementos.
Saludos
hola guilledr
ResponderEliminardefines correctamente las propiedades DataTextField y DataValueField del dropdownlist ?
estas asignando el DataSource con un datatable, no uses dataset si solo vas a cargar una sola tabla, o sino usas ds.Tables[0] para asignar el datasource
saludos
Hola,
ResponderEliminareste ejemplo es muy bueno siempre y cuando en el segundo combo tengas los datos cargados con todos los posibles registros, con el campo que relaciona con el combo 1, Pero si el segundo no necesariamente tiene todos los posibles, sino que depende de una búsqueda en el servidor dependiendo de lo que se halla seleccionado en el primero, creo que solo está la opción de updatepanel.
hola Javier
ResponderEliminarla verdad no entendi el planteo que realizas
el updatepanel te ayudara a cargar los controles sin que se actualice toda la pagina, pero no se si es esto lo que buscas
saludos
Funciona muy bien
ResponderEliminary Como puedo hacerlo con tres DropDownList que tengo dentro del gridview y que cargue en cascada
ResponderEliminartu link de descarga esta caigo men, podria volverlo a subir?.
ResponderEliminarTu codigo me funciona, pero al selecionar el el segundo ddl(que no sea el de por defecto) que en tu caso seria el de album se me borran los otros dos, sabes porque?
ResponderEliminarCorrecto, se carga el primer drop, sin embargo cuando seleccionas un ítem de ese, deseas que se cargue el segundo de acuerdo a tu selección del primero, pero este se reinicia y queda en el primer ítem y no hay forma, si quitas el Autopostback entonces no se activa el segundo Drop. que problema con estos drop anidados o dependientes. Sugerencias..y gracias
ResponderEliminar