<< Click to Display Table of Contents >> GridView - Mestre-Detalhe |
![]() ![]() ![]() |
Descrição
Fazer um GridView com sub-registros. Mestre detalhe.
Ao clicar na primeira coluna "[+]" ele expande os registros-filhos e troca o link para [-]
Telas
Com 2 itens expandidos:
Tudo expandido:
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication5.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script type="text/javascript" src="grade_mestre_detalhe.js"></script>
</head>
<body>
<form id="form1" runat="server">
<div>
<br />
<asp:HyperLink ID="HyperLink1" NavigateUrl="#" OnClick="ShowAll()" runat="server">Expandir tudo</asp:HyperLink><br />
<asp:HyperLink ID="HyperLink2" NavigateUrl="#" OnClick="HideAll()" runat="server">Esconder tudo</asp:HyperLink><br />
<br />
<br />
<asp:GridView ID="Grid" runat="server" AutoGenerateColumns="False" AllowPaging="False" OnRowDataBound="Grid_RowDataBound"
CellPadding="5" ForeColor="#333333" GridLines="None" OnPageIndexChanging="Grid_PageIndexChanging" PageSize="3">
<AlternatingRowStyle BackColor="White" />
<Columns>
<asp:HyperLinkField Text="[+]" />
<asp:BoundField Visible="False" DataField="Id" />
<asp:BoundField DataField="Nome" HeaderText="Nome" />
<asp:BoundField DataField="Endereco" HeaderText="Endereço" />
<asp:BoundField DataField="Fone" HeaderText="Fone" />
<asp:BoundField DataField="Idade" HeaderText="Idade da pessoa" />
</Columns>
<FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
<RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
<SortedAscendingCellStyle BackColor="#FDF5AC" />
<SortedAscendingHeaderStyle BackColor="#4D0000" />
<SortedDescendingCellStyle BackColor="#FCF6C0" />
<SortedDescendingHeaderStyle BackColor="#820000" />
<PagerSettings Position="Bottom" />
</asp:GridView>
<asp:TextBox ID="txtExpandedDivs" runat="server" Visible="false"></asp:TextBox>
</div>
</form>
</body>
</html>
Default.aspx.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Grid.DataSource = Pessoa.Get();
Grid.DataBind();
}
}
protected void Grid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// cria uma grid "interna"
GridView NewDg = new GridView();
// algumas configurações visuais
NewDg.AutoGenerateColumns = true;
NewDg.Width = Unit.Percentage(100.00);
NewDg.Font.Size = 8;
NewDg.Font.Name = "Tahoma";
NewDg.HeaderStyle.HorizontalAlign = HorizontalAlign.Left;
NewDg.BorderColor = System.Drawing.Color.Black;
// id é o código de ligação entre a tabela pai e tabela filha
string id = DataBinder.Eval(e.Row.DataItem, "id").ToString();
// obtem os dados do filho
List<Filhos> lista = Filhos.Get(int.Parse(id));
if (lista.Count == 0)
NewDg.ShowFooter = true;
// joga os dados do filho (devidamente filtrado pelo registro mestre) para a grid filha
NewDg.DataSource = lista;
NewDg.DataBind();
// aqui entra a gambiarra, vamos montar uma nova renderização para a ultima celula da linha da grid
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
NewDg.RenderControl(htw);
// monta uma div "externa" e coloca invisível por fora da grid
string DivStart = "<div id='uniquename" + e.Row.RowIndex.ToString() + "' style='DISPLAY: none; '>";
string DivBody = sw.ToString();
string DivEnd = "</div>";
string FullDIV = DivStart + DivBody + DivEnd;
int LastCellPosition = e.Row.Cells.Count - 1;
int NewCellPosition = e.Row.Cells.Count - 2;
e.Row.Cells[0].ID = "CellInfo" + e.Row.RowIndex.ToString();
// aqui permite ajustar a cor caso esteja usando "zebra" no pai
if (e.Row.RowIndex % 2 == 0)
{
//set to regular row style
e.Row.Cells[LastCellPosition].Text = e.Row.Cells[LastCellPosition].Text + "</td><tr><td bgcolor='f5f5f5'></td><td colspan='" + NewCellPosition.ToString() + "'>" + FullDIV;
}
else
{
//set to alternative row style
e.Row.Cells[LastCellPosition].Text = e.Row.Cells[LastCellPosition].Text + "</td><tr><td bgcolor='d3d3d3'></td><td colspan='" + NewCellPosition.ToString() + "'>" + FullDIV;
}
// atribui a primeira coluna "[+]" os eventos de on-click que exibem e ocultam o div que contém a sub-grid
e.Row.Cells[0].Attributes["onclick"] = "HideShowPanel('uniquename" +
e.Row.RowIndex.ToString() + "'); ChangePlusMinusText('" +
e.Row.Cells[0].ClientID + "'); SetExpandedDIVInfo('" +
e.Row.Cells[0].ClientID + "','" + this.txtExpandedDivs.ClientID +
"', 'uniquename" + e.Row.RowIndex.ToString() + "');";
// ativa cursor de maozinha (por default é o de seleçao de texto
e.Row.Cells[0].Attributes["onmouseover"] = "this.style.cursor='pointer'";
e.Row.Cells[0].Attributes["onmouseout"] = "this.style.cursor='pointer'";
}
}
// este código permite paginação - veja o PageSize da gridview e o AllowPager
protected void Grid_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
// passa para nova pagina
Grid.DataSource = Pessoa.Get();
Grid.PageIndex = e.NewPageIndex;
Grid.DataBind();
}
}
Observações
Fonte: http://www.progtalk.com/viewarticle.aspx?articleid=54