Se ve mucho más profesional mostrar información con un aspecto similar a la imagen que acompaña a este post, no les parece?
Yo creo que eso está fuera de discusión, definitivamente, es un gol de media cancha…
Ahora la pregunta es: cómo hago eso? es dificil?
Para nada, es muy sencillo. Lo único que tenemos que hacer es poner un pequeño código en el evento RowDataBound del gridview.
Veamos un ejemplo completo:
1.- Vamos a añadir un gridview a nuestra página aspx:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField HeaderText="Categoría">
<ItemTemplate>
<%#Eval("Category")%>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Producto">
<ItemTemplate>
<%#Eval("Product")%>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
2.- Creamos un datatable y lo cargamos de datos:
Dim LastCategory As String = String.Empty
Dim CurrentRow As Integer = -1
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsPostBack Then Return
'creamos un datatable al vuelo...
Dim dt As New DataTable()
Dim myColumn As DataColumn
myColumn = New DataColumn()
myColumn.DataType = Type.GetType("System.String")
myColumn.ColumnName = "Category"
dt.Columns.Add(myColumn)
myColumn = New DataColumn()
myColumn.DataType = Type.GetType("System.String")
myColumn.ColumnName = "Product"
dt.Columns.Add(myColumn)
'esto permitirá cargarle datos al datatable
Dim Products As New List(Of ListItem)
Products = MyProducts()
Dim i As Integer = 0
For Each li As ListItem In Products
i += 1
Dim row As DataRow
row = dt.NewRow()
row("Category") = li.Text
row("Product") = li.Value
dt.Rows.Add(row)
Next
'enlazo el datatable al gridview...
'previamente lo ordeno alfabéticamente
Dim dv As DataView
dv = dt.DefaultView
dv.Sort = "Category ASC"
dt = dv.ToTable
GridView1.DataSource = dt
GridView1.DataBind()
End Sub
'función que permite cargar los productos
Private Function MyProducts() As List(Of ListItem)
Dim Products As New List(Of ListItem)
Products.Add(New ListItem("Fruta", "Manzana"))
Products.Add(New ListItem("Fruta", "Papaya"))
Products.Add(New ListItem("Verdura", "Zanahoria"))
Products.Add(New ListItem("Verdura", "Zapallo"))
Products.Add(New ListItem("Fruta", "Plátano"))
Products.Add(New ListItem("Fruta", "Uvas"))
Products.Add(New ListItem("Verdura", "Apio"))
Products.Add(New ListItem("Verdura", "Poro"))
Products.Add(New ListItem("Legumbre", "Lechuga"))
Products.Add(New ListItem("Legumbre", "Coliflor"))
Products.Add(New ListItem("Legumbre", "Beterraga"))
Products.Add(New ListItem("Vitamina", "PVM"))
Return Products
End Function
3.- Aquí está el código que me permite combinar celdas de una columna… para que tenga el aspecto que queremos:
Protected Sub GridView1_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim row As DataRowView = CType(e.Row.DataItem, DataRowView)
If LastCategory = row("Category") Then
If (GridView1.Rows(CurrentRow).Cells(0).RowSpan = 0) Then
GridView1.Rows(CurrentRow).Cells(0).RowSpan = 2
Else
GridView1.Rows(CurrentRow).Cells(0).RowSpan += 1
End If
e.Row.Cells.RemoveAt(0)
Else
e.Row.VerticalAlign = VerticalAlign.Top
LastCategory = row("Category").ToString()
CurrentRow = e.Row.RowIndex
End If
End If
End Sub
Analicemos el código del evento RowDataBound:
1.- Usamos una variable LastCategory que guarde el nombre de la categoría de la fila que vamos enlazando al gridview.
2.- Si el nombre de la nueva categoría es igual al que se guardó en la variable LastCategory lo que hacemos en combinar la celda con las anteriores celdas de la misma columna.
3.- Si el nombre de la nueva categoría es diferente, entonces no combinamos las celdas… y se actualiza el valor de LastCategory.
Es todo.
Ah, me olvidaba… no te olvides que para que la agrupación de celdas se realice correctamente, previamente debes ordenar por categorías, de manera alfabética… ya sea ascendente o descendente… porque sino las mismas categorías harán varios grupos.
;)
6 comentarios:
Muy Bien gracias segundo, me gustaria que crearas un post de QueryString de como pasar datos entre paginas pero orientado a sql server, creo que nos seria de mucha ayuda a todos los segidores de tu blog.
saludos
isidro
isidroca@gmail.com
Hola Isidro,
Gracias por tu comentario. Puedes explicar un poquito más detallado cómo quisieras el ejemplo de querystring?
(Opcional)Si lo prefieres puedes enviar la explicación a mi correo sserrano[at]jabs[dot]com[dot]pe
Saludos.
Segundo:
Saludos desde Chile; me base en tu codigo para combinar 2 celdas desde un Gridview q cargo a traves de un sqldatas, el problema es que este me queda corrido hacia la derecha a partir de la segunda fila ordenada e envio el codigo a ver si me puedes echar una ayuda...
Dim row As DataRowView = CType(e.Row.DataItem, DataRowView)
If e.Row.RowType = DataControlRowType.DataRow Then
If ultimonombre = row("NOMBRE") And fecha = row("FECHA") Then
If (GridView1.Rows(CurrentRow).Cells(0).RowSpan = 0) And (GridView1.Rows(CurrentRow).Cells(1).RowSpan = 0) Then
GridView1.Rows(CurrentRow).Cells(0).RowSpan = 2
GridView1.Rows(CurrentRow).Cells(1).RowSpan = 2
GridView1.Rows(CurrentRow).Cells(0).RowSpan = 2
GridView1.Rows(CurrentRow).Cells(1).RowSpan = 2
Else
GridView1.Rows(CurrentRow).Cells(0).RowSpan += 2
GridView1.Rows(CurrentRow).Cells(1).RowSpan += 2
End If
'e.Row.Cells(0).Visible = False
e.Row.Cells.RemoveAt(1)
Else
e.Row.VerticalAlign = VerticalAlign.Top
ultimonombre = row("NOMBRE").ToString()
fecha = row("FECHA").ToString()
CurrentRow = e.Row.RowIndex
End If
End If
si agrego esta linea "'e.Row.Cells(0).Visible = False" cuando me muestra la grilla anda excelente pero al momento de editar tengo problemas con el viewstate
Hola Ricardo,
no te entiendo muy bien...
qué quieres decir con que queda corrido? que ves una columna adicional a la derecha?
podrías mostrarmelo graficamente?
sube la imagen y me pasas la url.
por otro lado, cuántas columnas y cuántas filas tiene tu gridview?
Saludos desde Perú hermano chileno
Ya se que es un tema antiguo, pero para evitar el error que descuadra las columnas despues de editar, es mejor ocultarla que eliminarla.
En vez de usar: e.Row.Cells.RemoveAt(0);
Es mejor: e.Row.Cells[0].Visible = false;
Saludos.
Publicar un comentario