问题
I'm in desperate need of a creative solution. I have an asp.net 4.5 web app, where I generate a gridview with about 40-50 columns and rows vary between 1 and a few thousands.
Since it's so big, I put the gridview in a div, set a height and the overflow-y:scroll.
What I want is to be able to see the header when I scroll.
I tried to find answers online. First solution was to give the header a css class and set the position:absolute, thus poping out the header. The problem with this approach was that when the header pops out, it covers the first row and unless I set the height of row huge, I can't see the first row.
I tried making only the first row's height bigger and setting the vertical-align to bottom. This worked very nice. The problem is that I have implemented jquery tablesort on the header. When I sorted the table, the first row that has a huge height, gets burried and the rest of the rows scramble because they are being offset by that huge row.
I searched on stackoverflow and I found another thread about the same problem: How Can We Have A SCROLLABLE GridView With Fixed Header?
Here it suggested creating another table for the header. This is very nice, but the problem here is that I don't have a fixed size table. The columns nr vary and the rows value vary. So I made another gridview above the main one. I set the ShowHeaderWhenEmpty=true. I added the columns in the code behind. The problem now is that the columns are not the same width as the original gridview.
I tried to set the width in OnRowDataBound. I tried with jquery. Nothing works. The only thing that works is if I add the data of the original gridview and hide the rows. But can I hide them ? If I use display:none, the header width goes back like it doesn't even see the data. I managed to hide the rows with opacity:0.0
The problem here is that the page takes a long time to load, it's very slow and it doesn't even render properly.
So instead of adding all the data, I tried adding a single row. In this row, for each cell, I added the longest string on that column. This method worked the best, but the problem now is that some of the columns in the second gridview are not aligned with the original gridview.
Why? My best guess is that some cells have wrap enabled and when that longest string wraps, it doesn't wrap the same as other rows which might affect the column's width.
Now I don't have a clue where to look next. So if anyone has an idea of what I might try or maybe why some of the methods I tried haven't work please let me know.
UPDATE:
So I was thinking, since I'm already using the jquery tablesorter plugin, I could try to use the widget-scroller to have the header fixed. I found this page: https://mottie.github.io/tablesorter/docs/example-widget-scroller.html, but I haven't managed to enable the scroller. Current tablesorter version: TableSorter (FORK) v2.28.15
My code is this:
HTML
<div id="wrapper">
<asp:GridView ID="OnlineSearchGridView" runat="server" CssClass="tablesorter hover-highlight tablesorter-scroller tablesorter-scroller-table" Visible="false" EnableSortingAndPagingCallbacks="false" AutoGenerateColumns="true" OnRowDataBound="OnlineSearchGridView_RowDataBound" Height="50px" CellPadding="5" Font-Names="Arial" Font-Size="9pt">
<EditRowStyle Font-Names="Arial" Font-Size="9pt" />
<HeaderStyle BackColor="#666666" BorderColor="Black" Font-Names="Arial" Font-Size="9pt" ForeColor="White"/>
<RowStyle BorderStyle="Solid" Font-Names="Arial" Font-Size="9pt" BorderColor="Black" BorderWidth="1px" HorizontalAlign="Center"/>
</asp:GridView>
</div>
JS
jQuery.fn.insertTHead = function (selection)
{
return this.each(function ()
{
if (jQuery('thead', this).length == 0)
jQuery("<thead></thead>").prependTo(this).append(jQuery(selection, this))
})
}
$(document).ready(function ()
{
$("table")
.insertTHead("tr:first")//Calling the jquery function that will insert the thead after postback.
.tablesorter({
widgets: ['scroller'],
widgetOptions:
{
scroller_height: 300,
scroller_upAfterSort: true,
scroller_jumpToHeader: true,
scroller_barWidth: null
}
})
});
External files
<link rel="stylesheet" type="text/css" href="css/tablesort_style.css"/>
<script type="text/javascript" src="Scripts/jquery-latest.js"></script>
<script type="text/javascript" src="Scripts/jquery.tablesorter.js"></script>
<script type="text/javascript" src="Scripts/jquery.tablesorter.widgets.js"></script>
What is wrong with this picture ? Why isn't the scroller active ? I'm thinking because griview doesn't have colgroups ? Do I need to append them just like I'm doing with the thead?
Sorry about the long post.
回答1:
My solution was using ScrollableTablePlugin addon:
<script src="js/ScrollableTablePlugin_1.0_min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$('#<%=GridView1_resize.ClientID%>').Scrollable({
ScrollHeight: 600
});
});
GridView1_resize is quite a normal GridView:
<asp:GridView ID="GridView1_resize" runat="server" AutoGenerateColumns="False"
CellPadding="0" DataSourceID="ObjectDataSource1" EnableTheming="false"
EmptyDataText="Nessun rapportino" CssClass="presenzeCol">
<Columns>
<asp:BoundField DataField="Nome"
HeaderText="Cognome e Nome" SortExpression="Nome">
</asp:BoundField>
<asp:BoundField DataField="Matricola" HeaderText="Matr."
SortExpression="Matricola">
</asp:BoundField>
<asp:BoundField DataField="Email">
</asp:BoundField>
<asp:BoundField DataField="G1" HeaderText="1" DataFormatString="{0:f}">
</asp:BoundField>
<asp:BoundField DataField="G2" HeaderText="2" DataFormatString="{0:f}">
</asp:BoundField>
<asp:BoundField DataField="G3" HeaderText="3" DataFormatString="{0:f}">
</asp:BoundField>
<asp:BoundField DataField="G4" HeaderText=" 4" DataFormatString="{0:f}">
</asp:BoundField>
<asp:BoundField DataField="G5" HeaderText="5" DataFormatString="{0:f}">
</asp:BoundField>
<asp:BoundField DataField="G6" HeaderText="6" DataFormatString="{0:f}">
</asp:BoundField>
<asp:BoundField DataField="G7" HeaderText="7" DataFormatString="{0:f}">
</asp:BoundField>
<asp:BoundField DataField="G8" HeaderText="8" DataFormatString="{0:f}">
</asp:BoundField>
<asp:BoundField DataField="G9" HeaderText="9" DataFormatString="{0:f}">
</asp:BoundField>
<asp:BoundField DataField="G10" HeaderText="10" DataFormatString="{0:f}">
</asp:BoundField>
<asp:BoundField DataField="G11" HeaderText="11" DataFormatString="{0:f}">
</asp:BoundField>
<asp:BoundField DataField="G12" HeaderText="12" DataFormatString="{0:f}">
</asp:BoundField>
</Columns>
</asp:GridView>
来源:https://stackoverflow.com/questions/45239410/asp-net-gridview-tablesorter-with-fixed-header