J'ai un ASP.NET GridView qui a des colonnes qui ressemblent à ceci:
| Foo | Bar | Total1 | Total2 | Total3 |
Est-il possible de créer un en-tête sur deux lignes qui ressemble à ceci?
| | Totals |
| Foo | Bar | 1 | 2 | 3 |
Les données de chaque ligne resteront inchangées car il s'agit simplement d'afficher l'en-tête et de réduire l'espace horizontal occupé par la grille.
L'intégralité de GridView est triable au cas où cela compte. Je n'ai pas l'intention que la colonne "Totaux" ajoutée ait une fonctionnalité de tri.
Modifier:
Sur la base d’un des articles donnés ci-dessous, j’ai créé une classe qui hérite de GridView et ajoute la deuxième ligne d’en-tête dans.
namespace CustomControls
{
public class TwoHeadedGridView : GridView
{
protected Table InnerTable
{
get
{
if (this.HasControls())
{
return (Table)this.Controls[0];
}
return null;
}
}
protected override void OnDataBound(EventArgs e)
{
base.OnDataBound(e);
this.CreateSecondHeader();
}
private void CreateSecondHeader()
{
GridViewRow row = new GridViewRow(0, -1, DataControlRowType.Header, DataControlRowState.Normal);
TableCell left = new TableHeaderCell();
left.ColumnSpan = 3;
row.Cells.Add(left);
TableCell totals = new TableHeaderCell();
totals.ColumnSpan = this.Columns.Count - 3;
totals.Text = "Totals";
row.Cells.Add(totals);
this.InnerTable.Rows.AddAt(0, row);
}
}
}
Si vous êtes nouveau sur ASP.NET, comme moi, je vous ferai également remarquer que vous devez:
1) Inscrivez votre classe en ajoutant une ligne comme celle-ci à votre formulaire Web:
<%@ Register TagPrefix="foo" NameSpace="CustomControls" Assembly="__code"%>
2) Remplacez asp: GridView par le balisage précédent par foo: TwoHeadedGridView. N'oubliez pas la balise de fermeture.
Une autre édition:
Vous pouvez également le faire sans créer de classe personnalisée.
Ajoutez simplement un gestionnaire d'événements pour l'événement DataBound de votre grille, comme suit:
protected void gvOrganisms_DataBound(object sender, EventArgs e)
{
GridView grid = sender as GridView;
if (grid != null)
{
GridViewRow row = new GridViewRow(0, -1,
DataControlRowType.Header, DataControlRowState.Normal);
TableCell left = new TableHeaderCell();
left.ColumnSpan = 3;
row.Cells.Add(left);
TableCell totals = new TableHeaderCell();
totals.ColumnSpan = grid.Columns.Count - 3;
totals.Text = "Totals";
row.Cells.Add(totals);
Table t = grid.Controls[0] as Table;
if (t != null)
{
t.Rows.AddAt(0, row);
}
}
}
L'avantage du contrôle personnalisé est que vous pouvez voir la ligne d'en-tête supplémentaire dans la vue de conception de votre formulaire Web. La méthode du gestionnaire d’événements est cependant un peu plus simple.
Cet article devrait vous indiquer la bonne direction. Vous pouvez créer par programme la ligne et l'ajouter à la collection à la position 0.
J'ai adopté l'approche de réponse acceptée, mais j'ai ajouté l'en-tête au GridView existant au lieu d'un GridView hérité personnalisé.
Après avoir lié mon GridView, je procède comme suit:
/*Create header row above generated header row*/
//create row
GridViewRow row = new GridViewRow(0, -1, DataControlRowType.Header, DataControlRowState.Normal);
//spanned cell that will span the columns I don't want to give the additional header
TableCell left = new TableHeaderCell();
left.ColumnSpan = 6;
row.Cells.Add(left);
//spanned cell that will span the columns i want to give the additional header
TableCell totals = new TableHeaderCell();
totals.ColumnSpan = myGridView.Columns.Count - 3;
totals.Text = "Additional Header";
row.Cells.Add(totals);
//Add the new row to the gridview as the master header row
//A table is the only Control (index[0]) in a GridView
((Table)myGridView.Controls[0]).Rows.AddAt(0, row);
/*fin*/
Remarque pour ceux qui choisissent d'utiliser la méthode RowDataBound dans VB.NET
Si vous vous retrouvez avec trop de lignes d'en-tête supplémentaires, ajoutez une instruction If qui n'est exécutée que si la ligne d'en-tête de gridview n'est rien (ce qui signifie que c'est celle qui est actuellement liée).
If grid.HeaderRow Is Nothing Then
Vous devrez créer une classe qui étend gridview puis substitue la méthode CreateRow.
essayez ceci comme point de départ
Ajoutez t.EnableViewState = false;
après avoir ajouté la ligne:
Dim t As Table = TryCast(grid.Controls(0), Table)
If t IsNot Nothing Then
t.Rows.AddAt(0, row)
End If
t.EnableViewState = false;
Je voulais effectuer une tâche similaire, mais il fallait des boutons cliquables à l'intérieur de l'en-tête - rien de ce qui précède n'a fonctionné dans ce cas car les gestionnaires d'événements n'étaient pas câblés (en raison de la séquence des événements). Finalement, j'ai utilisé la balise headertemplate dans le templatefield approprié de la vue en grille. Le code html semble un peu plus lourd, mais les événements restent intacts sans code supplémentaire derrière l'effort. Par exemple
<asp:TemplateField >
<HeaderTemplate>
<div>
<div style="text-align: center;padding-bottom: 5px;">
text
</div>
<div>
<asp:Button ID="Button1" runat="server" Text="Apply to all" ToolTip="Apply to all - Special Bolt On" CssClass="sub_button input_btn_5" OnClick="ApplyButton1_Click" />
</div>
</div>
</HeaderTemplate>
<ItemTemplate>....
Jetez un oeil à cet article En-tête de grille de colonnes de rangées dynamiques multiples
Veuillez vous référer à https://stackoverflow.com/a/9333714/1060656
j'ai créé cet exemple de solution
Pour fonctionner dans votre système local, vous devrez créer 2 fichiers (un pour le contrôle et un aspx). Vous pouvez le faire soit un projet, soit 2 projets.
fichier aspx ==> programme de test
public class GridViewPlus : GridView
{
public event EventHandler<CustomHeaderEventArgs> CustomHeaderTableCellCreated;
private GridViewPlusCustomHeaderRows _rows;
public GridViewPlus() : base ()
{
_rows = new GridViewPlusCustomHeaderRows();
}
/// <summary>
/// Allow Custom Headers
/// </summary>
public bool ShowCustomHeader { get; set; }
[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
[MergableProperty(false)]
public GridViewPlusCustomHeaderRows CustomHeaderRows
{
get {return _rows; }
}
protected virtual void OnCustomHeaderTableCellCreated(CustomHeaderEventArgs e)
{
EventHandler<CustomHeaderEventArgs> handler = CustomHeaderTableCellCreated;
// Event will be null if there are no subscribers
if (handler != null)
{
// Use the () operator to raise the event.
handler(this, e);
}
}
protected override void OnRowCreated(GridViewRowEventArgs e)
{
if (ShowCustomHeader && e.Row.RowType == DataControlRowType.Header) return;
base.OnRowCreated(e);
}
protected override void PrepareControlHierarchy()
{
//Do not show the Gridview header if show custom header is ON
if (ShowCustomHeader) this.ShowHeader = false;
base.PrepareControlHierarchy();
//Safety Check
if (this.Controls.Count == 0)
return;
bool controlStyleCreated = this.ControlStyleCreated;
Table table = (Table)this.Controls[0];
int j = 0;
if (CustomHeaderRows ==null )return ;
foreach (TableRow tr in CustomHeaderRows)
{
OnCustomHeaderTableCellCreated(new CustomHeaderEventArgs(tr,j));
table.Rows.AddAt(j, tr);
tr.ApplyStyle(this.HeaderStyle);
j++;
}
}
}
public class GridViewPlusCustomHeaderRows : System.Collections.CollectionBase
{
public GridViewPlusCustomHeaderRows()
{
}
public void Add(TableRow aGridViewCustomRow)
{
List.Add(aGridViewCustomRow);
}
public void Remove(int index)
{
// Check to see if there is a widget at the supplied index.
if (index > Count - 1 || index < 0)
// If no widget exists, a messagebox is shown and the operation
// is cancelled.
{
throw (new Exception("Index not valid"));
}
else
{
List.RemoveAt(index);
}
}
public TableRow Item(int Index)
{
// The appropriate item is retrieved from the List object and
// explicitly cast to the Widget type, then returned to the
// caller.
return (TableRow)List[Index];
}
}
public class CustomHeaderEventArgs : EventArgs
{
public CustomHeaderEventArgs(TableRow tr ,int RowNumber )
{
tRow = tr;
_rownumber = RowNumber;
}
private TableRow tRow;
private int _rownumber = 0;
public int RowNumber { get { return _rownumber; } }
public TableRow HeaderRow
{
get { return tRow; }
set { tRow = value; }
}
}
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Example1();
GridViewExtension1.CustomHeaderTableCellCreated += new EventHandler<CustomHeaderEventArgs>(GridViewExtension1_CustomHeaderTableCellCreated);
}
void GridViewExtension1_CustomHeaderTableCellCreated(object sender, CustomHeaderEventArgs e)
{
TableRow tc = (TableRow)e.HeaderRow;
tc.BackColor = System.Drawing.Color.AliceBlue;
}
private void Example1()
{
System.Data.DataTable dtSample = new DataTable();
DataColumn dc1 = new DataColumn("Column1",typeof(string));
DataColumn dc2 = new DataColumn("Column2",typeof(string));
DataColumn dc3 = new DataColumn("Column3",typeof(string));
DataColumn dc4 = new DataColumn("Column4",typeof(string));
// DataColumn dc5 = new DataColumn("Column5",typeof(string));
dtSample.Columns.Add(dc1);
dtSample.Columns.Add(dc2);
dtSample.Columns.Add(dc3);
dtSample.Columns.Add(dc4);
// dtSample.Columns.Add(dc5);
dtSample.AcceptChanges();
for (int i = 0; i < 25; i++)
{
DataRow dr = dtSample.NewRow();
for (int j = 0; j < dtSample.Columns.Count; j++)
{
dr[j] = j;
}
dtSample.Rows.Add(dr);
}
dtSample.AcceptChanges();
//GridViewExtension1.ShowHeader = false;
GridViewExtension1.ShowCustomHeader = true;
/*
*=======================================================================
* |Row 1 Cell 1 | Row 1 Col 2 (Span=2) | Row 1 Col 3 |
* | | | |
*=======================================================================
* |Row 2 Cell 1 | | | |
* | | Row 2 Col 2 | Row 2 Col 3 |Row 2 Col 4 |
*=======================================================================
*
*
*
*
* */
// SO we have to make 2 header row as shown above
TableRow TR1 = new TableRow();
TableCell tcR1C1 = new TableCell();
tcR1C1.Text = "Row 1 Cell 1";
tcR1C1.ColumnSpan = 1;
TR1.Cells.Add(tcR1C1);
TableCell tcR1C2 = new TableCell();
tcR1C2.Text = "Row 1 Cell 2";
tcR1C2.ColumnSpan = 2;
TR1.Cells.Add(tcR1C2);
TableCell tcR1C3 = new TableCell();
tcR1C3.Text = "Row 1 Cell 3";
tcR1C3.ColumnSpan = 1;
TR1.Cells.Add(tcR1C3);
GridViewExtension1.CustomHeaderRows.Add(TR1);
TableRow TR2 = new TableRow();
TableCell tcR2C1 = new TableCell();
tcR2C1.Text = "Row 2 Cell 1";
tcR2C1.ColumnSpan = 1;
TR2.Cells.Add(tcR2C1);
TableCell tcR2C2 = new TableCell();
tcR2C2.Text = "Row 2 Cell 2";
tcR2C2.ColumnSpan = 1;
TR2.Cells.Add(tcR2C2);
TableCell tcR2C3 = new TableCell();
tcR2C3.Text = "Row 2 Cell 3";
tcR2C3.ColumnSpan = 1;
TR2.Cells.Add(tcR2C3);
TableCell tcR2C4 = new TableCell();
tcR2C4.Text = "Row 2 Cell 4";
tcR2C4.ColumnSpan = 1;
TR2.Cells.Add(tcR2C4);
GridViewExtension1.CustomHeaderRows.Add(TR2);
GridViewExtension1.DataSource = dtSample;
GridViewExtension1.DataBind();
}
}