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.
Escrito por Fernando Sanchez 
