¿Cómo consigo que Gridview renderice THEAD?

112

¿Cómo obtengo el GridViewcontrol para representar las <thead> <tbody>etiquetas? Sé .UseAccessibleHeadersque lo hace en <th>lugar de hacerlo <td>, pero no puedo hacer <thead>que aparezca.

Andrew Bullock
fuente
FYI: UseAccessibleHeader es "verdadero" de forma predeterminada, por lo que no es necesario configurarlo. msdn.microsoft.com/en-us/library/…
MikeTeeVee

Respuestas:

187

Esto debería hacerlo:

gv.HeaderRow.TableSection = TableRowSection.TableHeader;
Phil Jenkins
fuente
69
La HeaderRowpropiedad será nullhasta que GridViewse hayan vinculado los datos, así que asegúrese de esperar hasta que se haya producido la vinculación de datos antes de ejecutar la línea de código anterior.
bdukes
6
Como se comenta a continuación, con ASP.NET 4.5 al menos después de que el enlace no sea lo suficientemente tarde; sin embargo, funciona en OnPreRender.
philw
Tengo una vista de cuadrícula con subencabezados personalizados agregados. Cada uno de estos subtítulos muestra datos de la fuente de datos. La razón por la que quería renderizar theades para usarlo en jQuery. Sin embargo, después de renderizar el encabezado, tbodyno parece estar disponible. ¿Qué puede faltar en mi caso?
bonCodigo
1
Descubrí que todavía había problemas durante la devolución y coloqué el código en el evento de enlace de datos que abordaba todos los escenarios.
James Westgate
Traigo mis datos de una base de datos cuando el usuario hace clic en un botón. En ese caso, a la vista de cuadrícula le falta la etiqueta thead. ¿Alguna ayuda?
Touinta
25

Yo uso esto en OnRowDataBoundcaso de:

protected void GridViewResults_OnRowDataBound(object sender, GridViewRowEventArgs e) {
    if (e.Row.RowType == DataControlRowType.Header) {
        e.Row.TableSection = TableRowSection.TableHeader;
    }
}
Neto Kuhn
fuente
7
Esta es la única solución que funcionó para mí. ¿Quién diseñó estos terribles controles?
EKW
2
Inserté su código en el evento OnRowCreated y lo hice funcionar correctamente.
yougotiger
Esta es la mejor solución porque elimina el riesgo (y la verificación requerida) de que TableSection sea nulo si no hay filas dentro del DataSource.
EvilDr
1
Para su información, si GridViewestá dentro de una UpdatePanely una devolución de datos asíncrona es causada por algún otro control, entonces el OnRowDataBoundevento no se generará, por lo que el código en esta respuesta no se ejecutará, lo que dará como resultado que se GridViewvuelva a renderizar sin <thead>etiquetas ... suspiro . Para apuntar a este caso, introduzca el código de la respuesta aceptada en el controlador de PreRendereventos de gridView (como sugiere la respuesta de ASalvo ).
Mr.Z
Esta es la respuesta correcta, ya que utiliza correctamente el flujo de trabajo de WebForms.
Marcel
10

El código de la respuesta debe continuar Page_Loado GridView_PreRender. Lo puse en un método que se llamó después Page_Loady obtuve un NullReferenceException.

ASalvo
fuente
4
También puedes poner en DataBoundevento. grid.DataBound += (s, e) => { grid.HeaderRow.TableSection = TableRowSection.TableHeader; };
BrunoLM
4
No sé si esto es diferente en .NET 4.5 ahora ... pero obtengo que HeaderRow es nulo en los controladores de eventos _DataBound y _PreRender. Esto podría estar relacionado con el hecho de que estoy usando la nueva función "Enlace de modelos" de ASP.NET Web Forms en gridView.
ClearCloud8
7

Utilizo el siguiente código para hacer esto:

Las ifdeclaraciones que agregué son importantes.

De lo contrario (dependiendo de cómo renderice su cuadrícula) lanzará excepciones como:

La tabla debe contener secciones de filas en orden de encabezado, cuerpo y pie de página.

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);
}

El thisobjeto es mi GridView.

De hecho, anulé Asp.net GridView para hacer mi propio control personalizado, pero puede pegar esto en su página aspx.cs y hacer referencia a GridView por nombre en lugar de usar el enfoque de vista de cuadrícula personalizada.

FYI: No he probado la lógica del pie de página, pero sé que esto funciona para los encabezados.

MikeTeeVee
fuente
5

Esto funciona para mi:

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;
    }
}

Esto se probó en VS2010.

Felipe Delgado
fuente
2

Cree una función y use esa función en su PageLoadevento de esta manera:

La función es:

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

El PageLoadevento es:

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

Sé que esto es antiguo, pero aquí hay una interpretación de la respuesta de MikeTeeVee, para una vista de cuadrícula estándar:

página aspx:

<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
fuente
0

También puede usar jQuery para agregarlo. Esto evita el problema con TableRowSection.TableHeader donde se coloca en PostBack.

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

Miguel
fuente