Jak zmusić Gridview do renderowania THEAD?

112

Jak uzyskać GridViewkontrolę nad renderowaniem <thead> <tbody>tagów? Wiem .UseAccessibleHeaders, że <th>zamiast tego wstawia <td>, ale nie mogę się <thead>pojawić.

Andrew Bullock
źródło
FYI: UseAccessibleHeader ma domyślnie wartość „true”, więc nie musisz jej ustawiać. msdn.microsoft.com/en-us/library/…
MikeTeeVee

Odpowiedzi:

187

To powinno wystarczyć:

gv.HeaderRow.TableSection = TableRowSection.TableHeader;
Phil Jenkins
źródło
69
HeaderRowNieruchomość będzie nullGridViewzostały dane związane, więc upewnij się, aby poczekać do wiązania z danymi nastąpiło przed wykonaniem powyższej linii kodu.
bdukes
6
Jak w komentarzu poniżej, w ASP.NET 4.5 przynajmniej po powiązaniu nie jest wystarczająco późno - działa jednak w OnPreRender.
philw
Mam widok siatki z dodanymi niestandardowymi nagłówkami podrzędnymi. Każdy z tych nagłówków podrzędnych zawiera dane ze źródła danych. Powodem, dla którego chciałem renderować, theadjest użycie go w jQuery. Jednak po wyrenderowaniu nagłówka tbodyplik nie wydaje się być dostępny. Czego może brakować w moim przypadku?
bonCodigo
1
Odkryłem, że nadal występują problemy podczas ogłaszania zwrotnego i umieściłem kod w zdarzeniu związanym z danymi, które dotyczyło wszystkich scenariuszy.
James Westgate
Pobieram dane z bazy danych, gdy użytkownik kliknie przycisk. W takim przypadku w widoku siatki brakuje tagu thead. Jakaś pomoc?
touinta
25

Używam tego w OnRowDataBoundprzypadku:

protected void GridViewResults_OnRowDataBound(object sender, GridViewRowEventArgs e) {
    if (e.Row.RowType == DataControlRowType.Header) {
        e.Row.TableSection = TableRowSection.TableHeader;
    }
}
Neto Kuhn
źródło
7
To jedyne rozwiązanie, które u mnie zadziałało. Kto zaprojektował te okropne elementy sterujące?
EKW
2
Wstawiłem twój kod do zdarzenia OnRowCreated i sprawiłem, że działa poprawnie.
yougotiger
Jest to najlepsze rozwiązanie, ponieważ eliminuje ryzyko (i wymagane sprawdzenie), że TableSection ma wartość null, jeśli żadne wiersze nie znajdują się w DataSource.
EvilDr
1
Fyi, jeśli GridViewznajduje się w obrębie an UpdatePaneli postback asynchroniczny jest spowodowany przez jakąś inną kontrolkę, to OnRowDataBoundzdarzenie nie zostanie zgłoszone, więc kod w tej odpowiedzi nie zostanie wykonany, co spowoduje GridViewpowrót do renderowania bez <thead>tagów ... westchnij . Aby wskazać ten przypadek, wepchnij kod z zaakceptowanej odpowiedzi do programu PreRenderobsługi zdarzeń gridView (podobnie jak sugeruje odpowiedź ASalvo ).
Pan Z
To jest poprawna odpowiedź, ponieważ poprawnie wykorzystuje przepływ pracy WebForms.
Marcel
10

Kod w odpowiedzi musi trwać dalej Page_Loadlub GridView_PreRender. Umieściłem to w metodzie, która została wywołana później Page_Loadi otrzymałem NullReferenceException.

ASalvo
źródło
4
Możesz również umieścić w DataBoundwydarzeniu. grid.DataBound += (s, e) => { grid.HeaderRow.TableSection = TableRowSection.TableHeader; };
BrunoLM,
4
Nie wiem, czy teraz jest inaczej w .NET 4.5 ... ale otrzymuję nagłówek HeaderRow mający wartość null w programach obsługi zdarzeń _DataBound i _PreRender. Może to być związane z faktem, że używam nowej funkcji „Powiązanie modelu” w widoku gridView ASP.NET Web Forms.
ClearCloud8
7

Aby to zrobić, używam następującego kodu:

Do ifstwierdzenia, że dodawane są ważne.

W przeciwnym razie (w zależności od tego, jak renderujesz swoją siatkę), będziesz rzucać wyjątki, takie jak:

Tabela musi zawierać sekcje wierszy w kolejności nagłówka, treści i stopki.

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

thisObiekt jest moim GridView.

W rzeczywistości przesłoniłem widok GridView Asp.net, aby utworzyć własną niestandardową kontrolkę, ale możesz wkleić ją na stronie aspx.cs i odwołać się do GridView według nazwy, zamiast używać podejścia niestandardowego widoku siatki .

FYI: Nie testowałem logiki stopki, ale wiem, że to działa w przypadku nagłówków.

MikeTeeVee
źródło
5

To działa dla mnie:

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

Próbowano tego w VS2010.

Felipe Delgado
źródło
2

Wiem, że to jest stare, ale oto interpretacja odpowiedzi Mike'aTeeVee dla standardowego widoku siatki:

strona 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
źródło
2

Utwórz funkcję i użyj tej funkcji w swoim PageLoadwydarzeniu w następujący sposób:

Funkcja to:

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

PageLoadWydarzenie jest:

protected void Page_Load(object sender, EventArgs e) {
        if (!IsPostBack)
        {
            MakeGridViewPrinterFriendly(grddata);
        }
}
Rajpurohit
źródło
0

Możesz również użyć jQuery, aby go dodać. Pozwala to uniknąć problemu z TableRowSection.TableHeader, w którym zostaje upuszczony na PostBack.

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

Michael
źródło