Hay una manera muy simple de llenar un combo, ya sea con los mismo valores o con distintos, en cada fila de una GridView en ASP.NET 2.0 (VS 2005). Lo primero que hay que hacer es (obviamente) dropear una gridview en la pagina y al insertar las columnas a la que queremos que sea nuestro combo la convertimos en Template de esta manera:
Hecho esto vamos a editar nuestro Template asi:
![]()
SIN USAR EDITITEMTEMPLATE
Dentro de ItemTemplate vamos a eliminar el Label que nos viene por defecto y dropear un DropDownList, no hace falta hacerlo en EditTemplate. Nos queda algo asi:
![]()
Al termina la edición nos queda algo asi:
![]()
Ahora nos pasamos a la parte HTML de la pagina para ver como nos queda la grilla:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="None"> <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <Columns> <asp:BoundField DataField="nomCom" HeaderText="Nombre" /> <asp:TemplateField HeaderText="Cargo"> <EditItemTemplate> <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> </EditItemTemplate> <ItemTemplate> <asp:DropDownList ID="DropDownList1" runat="server" Width="179px" DataTextField="CARGO" DataValueField="ID"> </asp:DropDownList> </ItemTemplate> </asp:TemplateField> </Columns> <RowStyle BackColor="#EFF3FB" /> <EditRowStyle BackColor="#2461BF" /> <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" /> <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" /> <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" /> <AlternatingRowStyle BackColor="White" /> </asp:GridView>
En mi caso todos los combos se llenan con la misma información por eso agrego el DataTextField ahí, esto se podría hacer del lado servidor.
Ahora lo mas importante del código esta en el evento RowDataBound de la grilla y es algo muy simple:
Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound Try If e.Row.RowType = DataControlRowType.DataRow Then 'DataRow Vale las row que tienen datos, de esta manera se saltea el header,el footer y el pager Dim ddl As DropDownList Dim dt2 As DataTable = LlenarTabla2() 'Celda 1 es donde esta el DropdownList Dim gvrow As GridViewRow = CType(e.Row.Cells(1).NamingContainer, GridViewRow) ddl = CType(gvrow.FindControl("DropDownList1"), DropDownList) ddl.ClearSelection() If ddl IsNot DBNull.Value Then ddl.DataSource = dt2 ddl.DataBind() 'Lleno el combo End If 'Después de llenar el combo se puede asignar el valor si es que tenia uno 'aca haciendo ddl.ddl.SelectedValue =... End If Catch ex As Exception Throw ex Finally End Try End Sub
Al ejecutar el proyecto la pagina nos queda de esta manera.
Adjunto el proyecto aqui.
USANDO EDITITEMTEMPLATE
También se pueden usar las hermosas características que nos proporciona .NET 2.0 y usar la columna CommandField con los botones de Editar y Actualizar.
En este caso el HTML nos quedaría de esta manera:
<asp:GridView ID="GridView2" runat="server" OnRowCancelingEdit="GridView2_RowCancelingEdit" OnRowEditing="GridView2_RowEditing" DataKeyNames="ID" OnRowUpdating="GridView2_RowUpdating" OnRowUpdated="GridView2_RowUpdated" ShowFooter="True" CellPadding="4" ForeColor="#333333" GridLines="None" AutoGenerateColumns="False" > <Columns> <asp:BoundField DataField="nomCom" HeaderText="Nombre" /> <asp:TemplateField HeaderText="Cargo"> <EditItemTemplate> <asp:DropDownList ID="DropDownList1" runat="server" Width="179px" DataTextField="CARGO" DataValueField="ID"> </asp:DropDownList> </EditItemTemplate> <ItemTemplate> <asp:Label ID="CargoText" runat="server" Text='<%# Eval("Cargo") %>'></asp:Label> </ItemTemplate> </asp:TemplateField> <asp:CommandField ShowEditButton="True" EditText="Editar" /> </Columns> <FooterStyle BackColor="#1C5E55" Font-Bold="True" ForeColor="White" /> <RowStyle BackColor="#E3EAEB" /> <EditRowStyle BackColor="#7C6F57" /> <SelectedRowStyle BackColor="#C5BBAF" Font-Bold="True" ForeColor="#333333" /> <PagerStyle BackColor="#666666" ForeColor="White" HorizontalAlign="Center" /> <HeaderStyle BackColor="#1C5E55" Font-Bold="True" ForeColor="White" /> <AlternatingRowStyle BackColor="White" /> </asp:GridView>
La primer diferencia es que el Dropdownlist ahora está dentro de una Tag edititemtemplate, esto es porque el combo no va aparecer desde un principio con el ejemplo anterior sino que solo se va a renderear para la row que quiera editar. Y que se mostrará en su lugar? Buena pregunta, para eso está el ItemTemplate que muestra algo por defecto en todas las rows o como en mi caso el valor de “Cargo” (esto va a salir del datatable que llenará la grilla, le agrego un valor por defecto).
Ahora vamos al código en VB en este caso no solo voy a necesitar RowDataBound sino también el evento RowEditing (el que entrará en acción cuando el usuario de click a la row):
Partial Class _Default Inherits System.Web.UI.Page Dim dt1 As DataTable = LlenarTabla1() Dim ht As Hashtable Dim flag As Boolean = FalseProtected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Try If Not Page.IsPostBack Then dBindData() End If Catch ex As Exception Throw ex End Try End Sub Sub dBindData() GridView2.DataSource = dt1 GridView2.DataBind() End Sub Protected Sub GridView2_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView2.RowDataBound Try If e.Row.RowType = DataControlRowType.DataRow Then 'DataRow Vale las row que tienen datos, de esta manera se saltea el header,el footer y el pager Dim ddl As DropDownList Dim dt2 As DataTable = LlenarTabla2() 'Celda 1 es donde esta el DropdownList Dim gvrow As GridViewRow = CType(e.Row.Cells(1).NamingContainer, GridViewRow) ddl = CType(gvrow.FindControl("DropDownList1"), DropDownList) If ddl IsNot Nothing Then ddl.ClearSelection() If ddl IsNot DBNull.Value Then ddl.DataSource = dt2 ddl.DataBind() 'Lleno el combo End If If flag = True Then 'si no esta vacio la hashtable se lo asigno al combo If Not String.IsNullOrEmpty(ht.Item(1)) Then ddl.SelectedValue = ddl.Items.FindByText(ht.Item(1)).Value End If End If End If Catch ex As Exception Throw ex Finally End Try End Sub Protected Sub GridView2_RowEditing(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles GridView2.RowEditing Dim idIndex As Integer = e.NewEditIndex Try GridView2.EditIndex = idIndex Dim lblTexto As Label = GridView2.Rows(idIndex).Cells(1).FindControl("CargoText") Dim ddl As DropDownList = GridView2.Rows(idIndex).Cells(1).FindControl("DropDownList1") If lblTexto IsNot Nothing Then 'Guardo un Hash con el valor que tiene el Label ht = New Hashtable 'siempre en el value 1 porque lo voy a usar solo para un valor ht.Add(1, lblTexto.Text) End If 'uso el flag para saber cuando esta rendereando 'el EditTemplate y no el Itemtemplate If ddl IsNot Nothing Then flag = True GridView2.DataSource = LlenarTabla1() GridView2.DataBind() Catch ex As Exception Throw ex Finally End Try End Sub End Class
Uso una HashTable para almacenar el valor que voy a tener que setear en el DropDownList una vez seleccionado, sino siempre mostraría el 1er valor del Combo.
Dejo este 2do ejemplo para descargar aca
Saludos.


Enero 29, 2008 a las 7:20 pm |
ok me parece muy bien todo, me has sacado me muchas dudas, pero estoy tratando de adaptarlo dentro de un edittemplate y no encuentro como pasarles los dados a los dropdown al darle clic a editar
Enero 30, 2008 a las 1:30 pm |
Actualizado para usar EditItemTemplate
Fecha: 4/2/2007
Saludos.
Febrero 19, 2008 a las 1:26 am |
tienes que declarar un evento y en el rowbound lo cachas
Febrero 23, 2008 a las 5:02 pm |
Hola muy bueno el tutorial.
Cómo se puede recibir el valor seleccionado? Tú has escrito lo siguiente:
‘Después de llenar el combo se puede asignar el valor si es que tenia uno
‘aca haciendo ddl.ddl.SelectedValue =…
Cómo puedo recibir ese valor? Yo lo tengo guardado en un field llamado Status en la lista que llena el GridView.
Febrero 26, 2008 a las 4:31 pm |
a ver si entendi bien, vos lo que podes hacer es usar ese ddl.selectedvalue que esta en el evento rowdatabound (que se ejecuta uno por cada fila) e ir poniendo el valor del status en el selectedValue, el SelectedValue es el valor de DataValueField por ejemplo un ID. Supongamos que tenes un datatable que es el que usas para bindear la grilla, en cada row de ese datatable vas a tener un status, entonces poder hacer datatable.select () para filtrar por la row en la que estas parado y ahi vas a hacer el ddl.selectedvalue =datatable(“status”).
Avisame cualquier cosa, postea algo de codigo y lo vemos.
Saludos
Marzo 31, 2008 a las 10:18 pm |
Como cosigues el Selectvalue sigo sin entender.
he estado investigando y en otros casos usan un control llamado
<asp:controlParameter
pero si me pueden resolver.
esque en el ejemplo que estoy haciendo si llena los combos pero nose como extraerlos
Abril 1, 2008 a las 2:43 pm |
si podes enviarme un poco de código, así lo vemos. Y te ayudo en todo lo que pueda. saludos
Mayo 7, 2008 a las 8:16 pm |
Como seria lo mismo en c# porfa.
Mayo 23, 2008 a las 4:48 pm |
Hola.
Soy nuevo en el uso del GridView y tengo una duda de tu codigo.
Cuando creas el campo CARGO y lo conviertes a Combo, los datos de DataTextField=”CARGO” DataValueField=”ID” son del mismo datasource o son de otro. La pregunta es porque en mi caso, el combo se llena de un catalogo y los datos de las filas del grid son de una tabla. Asi que, cuales datos debo manejar para DataTextField y para DataValueField.
Gracias
Mayo 23, 2008 a las 4:52 pm |
Hola de nuevo.
Las lineas siguientes que aparecen son necesarias???
Mayo 23, 2008 a las 7:09 pm |
Bueno a ver si entendi bien. Lo del Combo los Textfield y ValueField son los datos del Datasource. Por ejemplo si tu combo se llena por ejemplo con una Tabla que se tiene 2 columnas ID e Libro, esos 2 valores necesitas en el Combo. El combo se va llenar en todas las filas con el mismo origen. Entonces vos por un lado tenes las filas y por otro tenes el combo. El combo se llena siempre con lo mismo para todas las filas, fijate que yo hago:
ddl.DataSource = dt2
ddl.DataBind() ‘Lleno el combo
donde dt2 es un datatable en tu caso seria tu origen de datos. El dt2 y los Textfield y ValueField del combo deben ser iguales.
Saludos, espero que te haya ayudado.
PD: ahora si. estoy logueado
Mayo 23, 2008 a las 9:37 pm |
Hola de nuevo.
Como le puedo hacer si en la primer columna del grid que es un combo, tengo que desplegar la descripcion del catalogo y en la segunda columna del grid tengo que desplegar una descripcion en ingles que esta en el mismo catalogo, ambos datos no vienen en el origen de datos del grid, unicamente su clave.
Gracias
Mayo 27, 2008 a las 6:10 pm |
El evento RowDataBound se va a parar en cada Row de tu grid, ahi es donde tenes que llenar el combo de la 1er columna con los datos que necesites.
Dim gvrow As GridViewRow = CType(e.Row.Cells(1).NamingContainer, GridViewRow)
ddl = CType(gvrow.FindControl(“DropDownList1″), DropDownList)
Fijate que yo hago row.cells(1) esto es la 2da columna (porque empiezan en 0). Y ahí ddl vale el DropDownList que necesitas ponerle la descripción del catalago.
Saludos, cualquier cosa pone algo de código y lo vemos.
Julio 19, 2008 a las 2:36 pm |
Hola, yo tnego un problema similar a Pepe. Lo que quiero saber es como obtengo el valor ID que me viene en la grilla para poder pasarlo al dropDownlist (ddl.selectedvalue = ? ). Yo estuve intentando algo así e.Row.DataItem(“cod”) pero no me funciona…
Desde ya muchas gracias.
Julio 19, 2008 a las 3:00 pm |
Hola soy yo de nuevo.. jejej.
Lo solucioné de la siguiente manera. Lo paso por si alguno le sirve.
String idcod = null;
idcod = Convert.ToString(DataBinder.Eval(e.Row.DataItem, “Idcod”));
ddl.SelectedValue = idcod;
suerte.
Agosto 5, 2008 a las 4:49 pm |
Buen dia
Necesito ayuda…. le asigne datos de SQL 2000 a un DataTable…. todo eso esta bien… pero necesito saber si el valor de la columna esta en Null (nothing) para asi realizar xxx accion…
como lo hago en VB… estoy trabajando en ASP.NET 2.0 y VB..
Gracias
Agosto 5, 2008 a las 4:55 pm |
en .net 2.0 hay una Clase que se llama DBNull lo que tenes que hacer es lo siguiente:
if tu_valor_que_es_null is dbnull.value then
‘Entrara aca si el valor es nulo
end if
Agosto 28, 2008 a las 4:00 pm |
Muy Buen Artículo la verdad… Gracias!
Diciembre 19, 2008 a las 10:18 pm |
tengo un problema ..ya que tengo dos gridview rn una form web los dos contienen varios ddl el problem es que en el grid 1 se muestra la informacion sin problema, pero en el segundo todos los ddl muestran el primer valor…
Podrias ayudarme??????????
Marzo 3, 2009 a las 9:12 am |
Otra forma de hacerlo mas simple:
<!—->
<asp:DropDownList ID=”selTrans” DataSource=”" DataTextField=”sNombre” DataValueField=”id” SelectedValue=”" Runat=server EnableViewState=False>
Marzo 3, 2009 a las 9:19 am |
Otra forma de hacerlo mas simple:
<!—->
<asp:DropDownList ID=”selTrans” DataSource=”” DataTextField=”sNombre” DataValueField=”id” SelectedValue=”” Runat=server EnableViewState=False>
Lo que esta entre son etiquetas de servidor y asi no necitamos usar el evento RowDataBound
Septiembre 13, 2009 a las 5:47 pm |
hola
tengo un dropdownlist que lleno desde la bd, contiene la descripcion de una categoria, pero quisiera acceder a la clave de la categoria al seleccionar esa descripcion. como le puedo hacer?
gracias.