Introduzione
In questo articolo, vedremo come applicare ad un controllo GridView di Asp.Net 4 un pannello di espansione, che visualizza altre informazioni per una determinata riga della griglia, il tutto come mostrato in figura 1.
Figura 1
Ogni riga della griglia, ha un immagine, che al click (sul simbolo piu) permette di visualizzare un pannello composto da controlli label, informazioni su quel determinato record.
Per ogni riga avremmo diversi dati, in riferimenti al codice id di quel record.
Supponendo di avere una tabella anagrafica, nella quale si trova un campo IdPersona, un campo nome ed un campo Cognome, in relazione ad un’altra tabella denominata Dettaglio persona con un campo nome ed un campo codice, oltre al campo id chiave e idpersona, della tabella anagrafica. In questo modo avremmo una relazione di tabelle, che possiamo applicare nella griglia.
Nel nostro articolo, utilizzeremo le classi, ma tale esempio si può utilizzare benissimo anche con fonti dati provenienti da un databse.
Creazione delle classi.
Si crea una classe di nome Persona e una di tipo DettaglioPersona. Nella classe presona, si creano tre proprietà una di tipo intero (IdPersona) e due di tipo stirnga (nome e cognome) il tutto come riportato in nel codice qui sottostante.
VB.Net
Public Class Persona
Public Property IDPersona As Int32
Public Property Nome As String
Public Property Cognome As String
End Class
C#
public class Persona
{
public Int32 IDPersona { get; set; }
public string Cognome { get; set; }
public string Nome { get; set; }
}
Mentre nella classe Dettaglio persona si crea una proprietà di tipo intero, denominata IdPersona, a cui sarà relazionata la classe Persona, due proprietà di tipo stringa, denominate rispettivamente Citta e Codice.
Qui di seguito si riporta il codice delle suddette dichiarazioni.
VB.Net
Public Class DettaglioPersona
Public Property IDPersona As Int32
Public Property Citta As String
Public Property Codice As String
End Class
C#
public class DettaglioPersona
{
public Int32 IDPersona { get; set; }
public string Citta { get; set; }
public string codice { get; set; }
}
}
Creazione della pagina ASPX.
Passiamo in visualizzazione html per quanto riguarda la pagina ASPX, la funzione Espandi, permette di cambiare l’immagine di espansione e visualizzare o nascondere il panello, le immagini, sono state aggiunte al progetto.
Qui di seguito si riporta la funzione completa Javascript, che intercetta il pulsante e cambia l’immagine.
<script language="javascript" type="text/javascript">
function espandi(obj, row) {
var div = document.getElementById(obj);
var img = document.getElementById('img' + obj);
if (div != null) {
if (div.style.display == "none") {
div.style.display = "block";
if (row == 'alt') {
img.src = "/meno.gif";
}
else {
img.src = "meno.gif";
}
img.alt = "Clicca per nascondere";
}
else {
div.style.display = "none";
if (row == 'alt') {
img.src = "/piu.gif";
}
else {
img.src = "/piu.gif";
}
img.alt = "Clicca per aprire";
}
}
}
</script>
Aggiungiamo nella pagina web, un controllo gridView, impostiamo l’evento OnRowDataBound, in modo che in tale evento, intercettiamo il singolo record ed aggiungiamo il pannello.
Si aggiungono quattro colonne, di tipo templateField, nella prima, impostiamo il codice per la visualizzazione delle immagini (visualizzare (meno) e nascondere (piu) ) e il relativo cambio. Due colonne contenenti il valore delle proprietà Nome e Cognome, ed una colonna in cui si crea una tabella html (table) contenente un controllo di tipo panel, due controlli di tipo table lato server ed un controllo di tipo label.
Qui di seguito si riporta il codice completo html del controllo gridview
<asp:GridView ID="GrvAnagrafica" runat="server" AutoGenerateColumns="False" DataKeyNames="IDPersona"
OnRowDataBound="GrvAnagrafica_RowDataBound" CellPadding="4" ForeColor="#333333"
GridLines="None">
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<a href="javascript:espandi('div<%# Eval("IDPersona") %>', 'one');">
<img id="imgdiv<%# Eval("IDPersona") %>" alt="Dettaglio informazioni" src="/piu.gif" />
</a>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Nome" SortExpression="Nome">
<ItemTemplate>
<asp:Label ID="lblNome" runat="server" Text='<%# Bind("Nome") %>'></asp:Label></ItemTemplate>
<HeaderStyle HorizontalAlign="Left" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Cognome" SortExpression="Cognome">
<ItemTemplate>
<asp:Label ID="lblCognome" runat="server" Text='<%# Bind("Cognome") %>'></asp:Label></ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<tr>
<td colspan="100%">
<div id="div<%# Eval("IDPersona") %>">
<asp:Panel runat="server" ID="pnlSchedaDettaglio">
<table id="Table1" runat="server">
<tr>
<td colspan="70">
<asp:Label ID="Label1" runat="server" Text="Dettaglio Persona" Font-Bold="true" ForeColor="Red"></asp:Label>
</td>
</tr>
</table>
<asp:Table ID="tblSchedaDettaglio" runat="server">
</asp:Table>
</asp:Panel>
</div>
</td>
</tr>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowEditButton="False" SelectText="Modifica" />
<asp:CommandField ShowDeleteButton="False" />
</Columns>
<EditRowStyle BackColor="#999999" />
<FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<SortedAscendingCellStyle BackColor="#E9E7E2" />
<SortedAscendingHeaderStyle BackColor="#506C8C" />
<SortedDescendingCellStyle BackColor="#FFFDF8" />
<SortedDescendingHeaderStyle BackColor="#6F8DAE" />
</asp:GridView>
Il controllo table, visualizzerà i titoli e le varie righe, che andremmo a caricare dinamicamente, mentre il controllo label, le varie informazioni.
Stesura di codice
Ora passiamo in visualizzazione codice.
Si creano due funzioni, una che permetterà di valorizzare la griglia, e l’altra di visualizzare il dettaglio della singola riga.
Qui di seguito si riporta un esempio di codice delle due funzioni.
VB.Net
Private Function CaricaDati() As List(Of Persona)
'carico 2 dati di tipo persona
Dim persone As New List(Of Persona)
Dim pers As New Persona()
pers.Cognome = "Mattei"
pers.Nome = "Emanuele"
pers.IDPersona = 1
persone.Add(pers)
pers = New Persona()
pers.Cognome = "Mattei2"
pers.Nome = "Emanuele2"
pers.IDPersona = 2
persone.Add(pers)
Return persone
End Function
Private Function CaricaDettaglioPersona() As List(Of DettaglioPersona)
Dim dettPersone As New List(Of DettaglioPersona)
Dim DettPersona As New DettaglioPersona()
DettPersona.Citta = "Roma"
DettPersona.Codice = "AA"
DettPersona.IDPersona = 1
dettPersone.Add(DettPersona)
DettPersona = New DettaglioPersona()
DettPersona.Citta = "Firenze"
DettPersona.Codice = "BB"
DettPersona.IDPersona = 1
dettPersone.Add(DettPersona)
DettPersona = New DettaglioPersona()
DettPersona.Citta = "Calabria"
DettPersona.Codice = "CC"
DettPersona.IDPersona = 2
dettPersone.Add(DettPersona)
Return dettPersone
End Function
C#
private List<Persona> CaricaDati()
{
//carico 2 dati di persona
List<Persona> persone = new List<Persona>();
Persona pers = new Persona();
pers.Cognome = "Mattei";
pers.Nome = "Emanuele";
pers.IDPersona = 1;
persone.Add(pers);
pers = new Persona();
pers.Cognome = "Mattei2";
pers.Nome = "Emanuele2";
pers.IDPersona = 2;
persone.Add(pers);
return persone;
}
private List<DettaglioPersona> CaricaDettaglioPersona()
{
List<DettaglioPersona> dettPersone = new List<DettaglioPersona>();
DettaglioPersona dettPersona = new DettaglioPersona();
dettPersona.Citta = "Roma";
dettPersona.codice = "AA";
dettPersona.IDPersona = 1;
dettPersone.Add(dettPersona);
dettPersona = new DettaglioPersona();
dettPersona.Citta = "Firenze";
dettPersona.codice = "BB";
dettPersona.IDPersona = 1;
dettPersone.Add(dettPersona);
dettPersona = new DettaglioPersona();
dettPersona.Citta = "Calabria";
dettPersona.codice = "CC";
dettPersona.IDPersona = 2;
dettPersone.Add(dettPersona);
return dettPersone;
}
Nell’evento load, valorizziamo la nostra riga, utilizzando la funzione CaricaPersona.
Qui di seguito si riporta il codice per l’evento load della form.
VB.Net
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim ListPersona As List(Of Persona) = CaricaDati()
GrvAnagrafica.DataSource = ListPersona
GrvAnagrafica.DataBind()
End Sub
C#
protected void Page_Load(object sender, EventArgs e)
{
List<Persona> listPersona = CaricaDati();
GrvAnagrafica.DataSource = listPersona;
GrvAnagrafica.DataBind();
}
Terminata questa parte, si passa all’evento rowDataBound, in cui andremmo ad intercettare la creazione della singola riga, ed eseguire una query Linq, per relazionare le due classi, e caricare dinamicamente il pannello
Qui di seguito si riporta il codice delle suddette operazioni.
VB.Net
Protected Sub GrvAnagrafica_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GrvAnagrafica.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
'Rilevo la tabella delle schede reati
Dim pnlSchedaDettaglio As Panel = e.Row.FindControl("pnlSchedaDettaglio")
Dim tblSchedaDettaglio As Table = pnlSchedaDettaglio.FindControl("tblSchedaDettaglio")
Dim valore As Int32 = CType(e.Row.DataItem, Persona).IDPersona
Dim ListDetPersona As List(Of DettaglioPersona) = CaricaDettaglioPersona()
Dim DettPersona = From pers In ListDetPersona
Where pers.IDPersona = valore
Select pers
tblSchedaDettaglio.Width = New Unit("100%")
'creo la riga
Dim trRiga As New TableRow()
tblSchedaDettaglio.Rows.Add(trRiga)
'colonna Città - imposta i dati
Dim TdColCitta As New TableCell()
TdColCitta.Width = New Unit("15%")
TdColCitta.Text = ""
trRiga.Cells.Add(TdColCitta)
'colonna Codice - imposta i dati
Dim TdColCodice As New TableCell()
TdColCodice.Width = New Unit("85%")
TdColCodice.Text = ""
trRiga.Cells.Add(TdColCodice)
Dim ContaElementi As Int16 = 0
For Each elemento In DettPersona
trRiga = New TableRow()
tblSchedaDettaglio.Rows.Add(trRiga)
'colonna Città - imposta i dati
TdColCitta = New TableCell()
TdColCitta.Width = New Unit("15%")
TdColCitta.Text = ""
trRiga.Cells.Add(TdColCitta)
'colonna Codice - imposta i dati
TdColCodice = New TableCell()
TdColCodice.Width = New Unit("85%")
TdColCodice.Text = ""
trRiga.Cells.Add(TdColCodice)
tblSchedaDettaglio.Rows(ContaElementi + 1).Cells(0).Text = elemento.Citta
tblSchedaDettaglio.Rows(ContaElementi + 1).Cells(1).Text = elemento.Codice
ContaElementi += 1
Next
End If
End Sub
C#
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Rilevo la tabella delle schede reati
Panel pnlSchedaDettaglio = e.Row.FindControl("pnlSchedaDettaglio") as Panel;
Table tblSchedaDettaglio = pnlSchedaDettaglio.FindControl("tblSchedaDettaglio") as Table;
Int32 valore = ((Persona)e.Row.DataItem).IDPersona;
List<DettaglioPersona> ListDetPersona = CaricaDettaglioPersona();
var DettPersona = from pers in ListDetPersona
where pers.IDPersona == valore
select pers;
tblSchedaDettaglio.Width = new Unit("100%");
//creo la riga
TableRow trRiga = new TableRow();
tblSchedaDettaglio.Rows.Add(trRiga);
//colonna Città - imposta i dati
TableCell TdColCitta = new TableCell();
TdColCitta.Width = new Unit("15%");
TdColCitta.Text = "";
trRiga.Cells.Add(TdColCitta);
//colonna Codice - imposta i dati
TableCell TdColCodice = new TableCell();
TdColCodice.Width = new Unit("85%");
TdColCodice.Text = "";
trRiga.Cells.Add(TdColCodice);
//Creo le colonne dei titoli
Label lblEtichettaCitta = new Label();
lblEtichettaCitta.Text = "Città";
lblEtichettaCitta.ID = "lblCitta";
tblSchedaDettaglio.Rows[0].Cells[0].Controls.Add(lblEtichettaCitta);
Label lblEtichettaTipoReato = new Label();
lblEtichettaTipoReato.Text = "Codice";
lblEtichettaTipoReato.ID = "lblCodice";
tblSchedaDettaglio.Rows[0].Cells[1].Controls.Add(lblEtichettaTipoReato);
Int16 ContaElementi = 0;
foreach (var elemento in DettPersona)
{
trRiga = new TableRow();
tblSchedaDettaglio.Rows.Add(trRiga);
//colonna Città - imposta i dati
TdColCitta = new TableCell();
TdColCitta.Width = new Unit("15%");
TdColCitta.Text = "";
trRiga.Cells.Add(TdColCitta);
//colonna Codice - imposta i dati
TdColCodice = new TableCell();
TdColCodice.Width = new Unit("85%");
TdColCodice.Text = "";
trRiga.Cells.Add(TdColCodice);
tblSchedaDettaglio.Rows[ContaElementi + 1].Cells[0].Text = elemento.Citta;
tblSchedaDettaglio.Rows[ContaElementi + 1].Cells[1].Text = elemento.codice;
ContaElementi += 1;
}
}
}
Come si vede dal codice precedente, dopo aver rilevare l’oggetto panel, situato nella colonna della griglia, si crea un istanza della tabella contenuta al suo interno, in questo modo si crea una tabella, contenente i vari campi (titoli e valori)
Conclusioni
L’articolo ha voluto illustrare al lettore le basi per la creazione di una gridview con un pannello che integri le informazioni per ogni singola riga. Nell’esempio è stato utilizzato un controllo di tipo Label, ma nulla vieta che si possa inserire un controllo di tipo combobox, calendar, o altro.