Prenons une simple classe "business" que l'on souhaite afficher dans une GridView:
public class DocumentAttache
{
public int TypeDocument { get; set; }
public string Nom { get; set; }
public string Description { get; set; }
}
Créons la grille dans une page ASP.NET
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<DocumentAttache> liste = new List<DocumentAttache>();
liste.Add(new DocumentAttache() { TypeDocument = 1, Nom = "Doc1", Description = "Description Doc1" });
liste.Add(new DocumentAttache() { TypeDocument = 1, Nom = "Doc2", Description = "Description Doc2" });
liste.Add(new DocumentAttache() { TypeDocument = 1, Nom = "Doc3", Description = "Description Doc3" });
liste.Add(new DocumentAttache() { TypeDocument = 2, Nom = "Doc4", Description = "Description Doc4" });
liste.Add(new DocumentAttache() { TypeDocument = 2, Nom = "Doc5", Description = "Description Doc5" });
liste.Add(new DocumentAttache() { TypeDocument = 3, Nom = "Doc7", Description = "Description Doc7" });
liste.Add(new DocumentAttache() { TypeDocument = 3, Nom = "Doc7", Description = "Description Doc7" });
this.GridView1.DataSource = liste;
this.GridView1.DataBind();
MergeColumn(this.GridView1, 0);
}
}
Comme vous avez pu le voir plus haut dans le remplissage de la gridview, il y a la dernière ligne du précédent code qui est "intéressante" pour le "merge des colonnes.
Mais qu'en est il derrière ?
Le merge des colonnes
Voici la réponse :
private static void MergeColumn(GridView gv, int position)
{
Dictionary<string, int> hash = new Dictionary<string, int>();
string currentText = string.Empty;
int count = 0;
int currentCell = 0;
do
{
GridViewRow dataRow = gv.Rows[currentCell++];
if (dataRow.RowType == DataControlRowType.DataRow)
{
bool sameText = dataRow.Cells[position].Text == currentText;
if (currentCell == gv.Rows.Count)
{
if (!sameText)
{
// Fin mais pas meme texte
if (count > 1)
hash.Add(currentText, count);
}
else
{
// Fin meme texte
hash.Add(currentText, count + 1);
}
}
else
{
// Pas meme texte
if (!sameText)
{
if (count > 1)
hash.Add(currentText, count);
currentText = dataRow.Cells[position].Text;
count = 0;
}
}
++count;
}
}
while (currentCell < gv.Rows.Count);
currentText = string.Empty;
foreach (GridViewRow row in gv.Rows)
{
if (row.RowType == DataControlRowType.DataRow &&
hash.ContainsKey(row.Cells[position].Text))
{
if (row.Cells[position].Text == currentText)
row.Cells.Remove(row.Cells[position]);
else
{
currentText = row.Cells[position].Text;
row.Cells[position].RowSpan = hash[currentText];
row.Cells[position].VerticalAlign = VerticalAlign.Middle;
}
}
}
}
Voici le résultat:
Evidement, je suis preneur pour simplifier mon code de merge ;-). Mais ce soir ... la migraine m'empêche d'optimiser =S
une réaction
1 De SuperDamz - 30/03/2009, 13:23
Desolé DotClear vire les indentations :
private static void MergeColumn(GridView gv, int position)
{
var qSpawns = gv.Rows.Cast<TableRow>().GroupBy(row => row.Cells[position].Text).GetEnumerator();
for (int i = 0, nextSpan = 0; i < gv.Rows.Count; i++)
if (i == nextSpan && qSpawns.MoveNext())
nextSpan += gv.Rows[i].Cells[position].RowSpan = qSpawns.Current.Count();
else
gv.Rows[i].Cells.RemoveAt(position);
}
Evidement, il faut dès le départ que les colonnes soient sorties de telle manière que l'on puisse les grouper correctement.