Wie bringe ich Gridview dazu, THEAD zu rendern?

112

Wie erhalte ich das GridViewSteuerelement zum Rendern der <thead> <tbody>Tags? Ich weiß , .UseAccessibleHeadersmacht es ausdrückte <th>statt <td>, aber ich kann nicht das bekommen <thead>scheinen.

Andrew Bullock
quelle
Zu Ihrer Information: UseAccessibleHeader ist standardmäßig "true", Sie müssen es also nicht festlegen. msdn.microsoft.com/en-us/library/…
MikeTeeVee

Antworten:

187

Dies sollte es tun:

gv.HeaderRow.TableSection = TableRowSection.TableHeader;
Phil Jenkins
quelle
69
Die HeaderRowEigenschaft bleibt bestehen, nullbis die GridViewDaten gebunden wurden. Warten Sie daher, bis die Datenbindung erfolgt ist, bevor Sie die obige Codezeile ausführen.
Bdukes
6
Wie unten erwähnt, ist ASP.NET 4.5 zumindest nach dem Binden nicht spät genug - es funktioniert jedoch in OnPreRender.
Philw
Ich habe eine Rasteransicht mit benutzerdefinierten Unterüberschriften hinzugefügt. Jeder dieser Unterheader zeigt Daten aus der Datenquelle an. Der Grund, warum ich rendern wollte, theadist die Verwendung in jQuery. Nach dem Rendern des Headers tbodyscheint der jedoch nicht verfügbar zu sein. Was kann in meinem Fall fehlen?
BonCodigo
1
Ich stellte fest, dass beim Postback immer noch Probleme auftraten, und platzierte den Code in dem datengebundenen Ereignis, das alle Szenarien abdeckte.
James Westgate
Ich bringe meine Daten aus einer Datenbank, wenn der Benutzer auf eine Schaltfläche klickt. In diesem Fall fehlt in der Rasteransicht das Thead-Tag. Irgendeine Hilfe?
Touinta
24

Ich benutze dies für den OnRowDataBoundFall:

protected void GridViewResults_OnRowDataBound(object sender, GridViewRowEventArgs e) {
    if (e.Row.RowType == DataControlRowType.Header) {
        e.Row.TableSection = TableRowSection.TableHeader;
    }
}
Neto Kuhn
quelle
7
Dies ist die einzige Lösung, die für mich funktioniert hat. Wer hat diese schrecklichen Kontrollen entworfen?
EKW
2
Ich habe Ihren Code in das OnRowCreated-Ereignis eingefügt und ihn ordnungsgemäß ausgeführt.
Yougotiger
Dies ist die beste Lösung, da dadurch das Risiko (und die erforderliche Überprüfung) beseitigt wird, dass der TableSection null ist, wenn sich keine Zeilen in der DataSource befinden.
EvilDr
1
Zu Ihrer Information, wenn sich das GridViewinnerhalb eines befindet UpdatePanelund ein asynchrones Postback durch ein anderes Steuerelement verursacht wird, wird das OnRowDataBoundEreignis nicht ausgelöst , sodass der Code in dieser Antwort nicht ausgeführt wird, was dazu führt, dass das GridViewRendern ohne <thead>Tags wiederhergestellt wird ... seufz . Um diesen Fall anzugehen, verschieben Sie den Code aus der akzeptierten Antwort in den PreRenderEreignishandler von gridView (ähnlich wie in der Antwort von ASalvo vorgeschlagen ).
Mr.Z
Dies ist die richtige Antwort, da der WebForms-Workflow ordnungsgemäß verwendet wird.
Marcel
10

Der Code in der Antwort muss weiter Page_Loadoder weitergehen GridView_PreRender. Ich habe es in eine Methode eingefügt, die nach aufgerufen wurde Page_Loadund eine bekam NullReferenceException.

ASalvo
quelle
4
Sie können auch DataBoundEreignis einfügen. grid.DataBound += (s, e) => { grid.HeaderRow.TableSection = TableRowSection.TableHeader; };
BrunoLM
4
Ich weiß nicht, ob dies in .NET 4.5 jetzt anders ist ... aber ich erhalte, dass die HeaderRow sowohl in den _DataBound- als auch in den _PreRender-Ereignishandlern null ist. Dies hängt möglicherweise damit zusammen, dass ich die neue Funktion "Modellbindung" von ASP.NET Web Forms in gridView verwende.
ClearCloud8
7

Ich benutze dazu den folgenden Code:

Die ifAussagen, die ich hinzugefügt habe, sind wichtig.

Andernfalls (abhängig davon, wie Sie Ihr Raster rendern) werden Ausnahmen ausgelöst wie:

Die Tabelle muss Zeilenabschnitte in der Reihenfolge von Kopf-, Kopf- und Fußzeile enthalten.

protected override void OnPreRender(EventArgs e)
{
    if ( (this.ShowHeader == true && this.Rows.Count > 0)
      || (this.ShowHeaderWhenEmpty == true))
    {
        //Force GridView to use <thead> instead of <tbody> - 11/03/2013 - MCR.
        this.HeaderRow.TableSection = TableRowSection.TableHeader;
    }
    if (this.ShowFooter == true && this.Rows.Count > 0)
    {
        //Force GridView to use <tfoot> instead of <tbody> - 11/03/2013 - MCR.
        this.FooterRow.TableSection = TableRowSection.TableFooter;
    }
    base.OnPreRender(e);
}

Das thisObjekt ist mein GridView.

Ich habe das Asp.net GridView tatsächlich überschrieben, um mein eigenes benutzerdefiniertes Steuerelement zu erstellen. Sie können dies jedoch in Ihre aspx.cs- Seite einfügen und das GridView nach Namen referenzieren, anstatt den benutzerdefinierten Gridview-Ansatz zu verwenden.

Zu Ihrer Information: Ich habe die Fußzeilenlogik nicht getestet, aber ich weiß, dass dies für Kopfzeilen funktioniert.

MikeTeeVee
quelle
5

Das funktioniert bei mir:

protected void GrdPagosRowCreated(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        e.Row.TableSection = TableRowSection.TableBody;
    }
    else if (e.Row.RowType == DataControlRowType.Header)
    {
        e.Row.TableSection = TableRowSection.TableHeader;
    }
    else if (e.Row.RowType == DataControlRowType.Footer)
    {
        e.Row.TableSection = TableRowSection.TableFooter;
    }
}

Dies wurde in VS2010 versucht.

Felipe Delgado
quelle
2

Erstellen Sie eine Funktion und verwenden Sie diese Funktion in Ihrer PageLoadVeranstaltung wie folgt:

Die Funktion ist:

private void MakeGridViewPrinterFriendly(GridView gridView) {  
    if (gridView.Rows.Count > 0) {          
        gridView.UseAccessibleHeader = true;  
        gridView.HeaderRow.TableSection = TableRowSection.TableHeader;  
    }  
} 

Die PageLoadVeranstaltung ist:

protected void Page_Load(object sender, EventArgs e) {
        if (!IsPostBack)
        {
            MakeGridViewPrinterFriendly(grddata);
        }
}
Rajpurohit
quelle
1

Ich weiß, dass dies alt ist, aber hier ist eine Interpretation der Antwort von MikeTeeVee für eine Standard-Rasteransicht:

aspx Seite:

<asp:GridView ID="GridView1" runat="server" 
    OnPreRender="GridView_PreRender">

aspx.cs:

    protected void GridView_PreRender(object sender, EventArgs e)
    {
        GridView gv = (GridView)sender;

        if ((gv.ShowHeader == true && gv.Rows.Count > 0)
            || (gv.ShowHeaderWhenEmpty == true))
        {
            //Force GridView to use <thead> instead of <tbody> - 11/03/2013 - MCR.
            gv.HeaderRow.TableSection = TableRowSection.TableHeader;
        }
        if (gv.ShowFooter == true && gv.Rows.Count > 0)
        {
            //Force GridView to use <tfoot> instead of <tbody> - 11/03/2013 - MCR.
            gv.FooterRow.TableSection = TableRowSection.TableFooter;
        }

    }
Jonathan Harris
quelle
0

Sie können es auch mit jQuery hinzufügen. Dies vermeidet das Problem mit TableRowSection.TableHeader, bei dem PostBack gelöscht wird.

$('#myTableId').prepend($("<thead></thead>").append($(this).find("#myTableId tr:first")));

Michael
quelle