【问题标题】:Gridview Freezing/Fixed Header loses background color when scrollingGridview 冻结/固定标题在滚动时会丢失背景颜色
【发布时间】:2014-03-13 03:01:54
【问题描述】:

我正在尝试为我的 gridview 实现一个冻结/固定的标题窗格。网格视图可以正常工作,就像将其渲染到此解决方案中一样。当此页面首次呈现时,页面看起来很完美。但是,当我尝试滚动信息时,背景颜色标题栏会与其余数据一起向上滚动。唯一被冻结的是 gridview 的文本标题,但背景在 gridview 滚动时是透明的。

我已经包含了这个页面的重要数据。但是,如果需要在下面的代码中添加更多信息,请告诉我。我尝试添加/调整 javascript、css、gridview 和 C# 设置,但没有成功。我被难住了。

注意:这是针对 IE 9 的。

页面模板信息...

<%@ Master Language="C#"  AutoEventWireup="true" CodeFile="Cosmetic.Wrapper.cs" Inherits="Cosmetic_Wrapper" %>
 <!DOCTYPE html>
 <html lang="en">
 <head runat="server">
      <meta charset="utf-8" />
      <asp:PlaceHolder runat="server">
       <%: Scripts.Render("~/bundles/modernizr") %>
      </asp:PlaceHolder>
 (other nonessential header garbage - If you really need this let me know)
 <asp:ContentPlaceHolder runat="server"  ID="Header"
 <script src="path/to/jquery-2.0.3.min.js"></script>
 <script src="path/to/jquery-2.0.3.js"></script>

 <script language="javascript" type="text/javascript">
     function CreateGridHeader(DataDiv, GridView1, HeaderDiv) {
         var DataDivObj = document.getElementById(DataDiv);
         var DataGridObj = document.getElementById(GridView1);
         var HeaderDivObj = document.getElementById(HeaderDiv);

         //********* Creating new table which contains the header row ***********
         var HeadertableObj = HeaderDivObj.appendChild(document.createElement('table'));

         DataDivObj.style.paddingTop = '0px';
         var DataDivWidth = DataDivObj.clientWidth;
         DataDivObj.style.width = '50000px';
         DataDivObj.style.width = '#507CD1';

         //********** Setting the style of Header Div as per the Data Div ************
         HeaderDivObj.className = DataDivObj.className;
         HeaderDivObj.style.cssText = DataDivObj.style.cssText;
         //**** Making the Header Div scrollable. *****
         HeaderDivObj.style.overflow = 'auto';
         //*** Hiding the horizontal scroll bar of Header Div ****
         HeaderDivObj.style.overflowX = 'hidden';
         //**** Hiding the vertical scroll bar of Header Div **** 
         HeaderDivObj.style.overflowY = 'hidden';
         HeaderDivObj.style.height = DataGridObj.rows[0].clientHeight + 'px';
         //**** Removing any border between Header Div and Data Div ****
         HeaderDivObj.style.borderBottomWidth = '0px';



         //********** Setting the style of Header Table as per the GridView ************
         HeadertableObj.className = DataGridObj.className;
         //**** Setting the Headertable css text as per the GridView css text 
         HeadertableObj.style.cssText = DataGridObj.style.cssText;
         HeadertableObj.border = '1px';
         HeadertableObj.rules = 'all';
         HeadertableObj.cellPadding = DataGridObj.cellPadding;
         HeadertableObj.cellSpacing = DataGridObj.cellSpacing;

         //********** Creating the new header row **********
         var Row = HeadertableObj.insertRow(0);
         Row.className = DataGridObj.rows[0].className;
         Row.style.cssText = DataGridObj.rows[0].style.cssText;
         Row.style.fontWeight = 'normal';



         //******** This loop will create each header cell *********
         for (var iCntr = 0; iCntr < DataGridObj.rows[0].cells.length; iCntr++) {
             var spanTag = Row.appendChild(document.createElement('td'));
             spanTag.innerHTML = DataGridObj.rows[0].cells[iCntr].innerHTML;
             var width = 0;
             //****** Setting the width of Header Cell **********
             if (spanTag.clientWidth > DataGridObj.rows[1].cells[iCntr].clientWidth) {
                 width = spanTag.clientWidth;
             }
             else {
                 width = DataGridObj.rows[1].cells[iCntr].clientWidth;
             }
             if (iCntr <= DataGridObj.rows[0].cells.length - 2) {
                 spanTag.style.width = width + 'px';
             }
             else {
                 spanTag.style.width = width + 20 + 'px';
             }
             DataGridObj.rows[1].cells[iCntr].style.width = width + 'px';
         }
         var tableWidth = DataGridObj.clientWidth;
         //********* Hidding the original header of GridView *******
         DataGridObj.rows[0].style.display = 'none';
         //********* Setting the same width of all the componets **********
         HeaderDivObj.style.width = DataDivWidth + 'px';
         DataDivObj.style.width = DataDivWidth + 'px';
         DataGridObj.style.width = tableWidth + 'px';
         HeadertableObj.style.width = tableWidth + 20 + 'px';
         return false;
     }

     function Onscrollfnction() {
         var div = document.getElementById('DataDiv');
         var div2 = document.getElementById('HeaderDiv');
         //****** Scrolling HeaderDiv along with DataDiv ******
         div2.scrollLeft = div.scrollLeft;
         return false;
     }

</script>
 </head>
  <body>
 (Insert top portion of page cosmetics here)
 <asp:ScriptManager runat="server">
    <Path>
        <%--To learn more about bundling Path in ScriptManager see http://go.microsoft.com/fwlink/?LinkID=272931&clcid=0x409 --%>
        <%--Framework Path--%>
        <asp:ScriptReference Name="MsAjaxBundle" />
        <asp:ScriptReference Name="jquery" />
        <asp:ScriptReference Name="jquery.ui.combined" />
        <asp:ScriptReference Name="WebForms.js" Assembly="System.Web" Path="~/Path/To/WebForms.js" />
        <asp:ScriptReference Name="WebUIValidation.js" Assembly="System.Web" Path="~/Path/To/WebUIValidation.js" />
        <asp:ScriptReference Name="MenuStandards.js" Assembly="System.Web" Path="~/Path/To/MenuStandards.js" />
        <asp:ScriptReference Name="GridView.js" Assembly="System.Web" Path="~/Path/To/GridView.js" />
        <asp:ScriptReference Name="DetailsView.js" Assembly="System.Web" Path="~/Path/To/DetailsView.js" />
        <asp:ScriptReference Name="TreeView.js" Assembly="System.Web" Path="~/Path/To/TreeView.js" />
        <asp:ScriptReference Name="WebParts.js" Assembly="System.Web" Path="~/Path/To/WebParts.js" />
        <asp:ScriptReference Name="Focus.js" Assembly="System.Web" Path="~/Path/To/Focus.js" />
        <asp:ScriptReference Name="WebFormsBundle" />
        <%--Site Path--%>

    </Path>
</asp:ScriptManager>
 <header>
   (More page cosmetics)
 </header>
 <div id="body">
<asp:ContentPlaceHolder runat="server" ID="FeaturedInfo" />
<section class="content-wrapper main-content clear-fix">
  <asp:ContentPlaceHolder runat="server" ID="MainBody" />
</section>
</div>
<footer>
 (nonessential footer info)
</footer>
</form>
</body>
</html>

ASP 页面

<%@ Page Title="ASP Page" Language="C#" MasterPageFile="~/Cosmetic.Wrapper" AutoEventWireup="true" CodeFile="asp-page.aspx.cs" Inherits="asp_page" %>

<asp:Content ID="Content1" ContentPlaceHolderID="Header" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="FeaturedInfo" Runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="MainBody" Runat="Server">

<style type="text/css">

    .GridViewStyle
    {    
        font-family:Verdana;
        font-size:11px;

        background-color: White; 
    }

    .GridViewHeaderStyle
    {
        font-family:Verdana;
        font-size:15px;
        position:fixed;

        background-color:#507CD1;
        color:black;
        height:40px;

    }

</style>

  <%--Insert SQL Datasource info here --%>

       <div>
        <%--Div contains the new header of the GridView--%>
        <div id="HeaderDiv">

        </div>
              <%--Wrapper Div which will scroll the GridView--%>
        <div id="DataDiv" style="overflow: auto; border: 1px solid olive; width: 2000px; height: 300px;" onscroll="Onscrollfnction();">

<asp:GridView ID="GridView1"  runat="server" AllowSorting="True" HeaderStyle-CssClass="GridViewHeaderStyle"  AutoGenerateColumns="False"  DataKeyNames="line" DataSourceID="SqlConn1"  ForeColor="#333333" GridLines="None">

        <columns>
        Place Bound/TemplateFields here
        </columns>


 <insert gridview cosmetic info here - if needed please let me know>
 </gridview>
 </div>
 </div>
 </asp:Content>

C#代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Configuration;
using System.Web.Security;
using System.Data.OleDb;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class asp_page : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (GridView1.Rows.Count > 0)
        {
            ClientScript.RegisterStartupScript(this.GetType(), "CreateGridHeader", "<script>CreateGridHeader('DataDiv', 'GridView1', 'HeaderDiv');</script>");
        }
    }
    protected void cmdClick_Click(object sender, EventArgs e)
    {
               ClientScript.RegisterStartupScript(this.GetType(), "CreateGridHeader", "<script>CreateGridHeader('DataDiv', 'GridView1', 'HeaderDiv');</script>");
    }



}

更新 - 2/27 - 10:16 PST

这是在将其输入空白 HTML 页面时呈现的代码。此示例中根本没有使用 C# 页面。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
</title>
    <script src="path/to/jquery-2.0.3.min.js"></script>  
<script src="path/to/jquery-2.0.3.js"></script> 
</head>
<body>
    <form method="post" action="test.aspx" id="form1">
<div class="aspNetHidden">
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="Insert Millions of random characters here" />
</div>

<script type="text/javascript">
    //<![CDATA[
    var theForm = document.forms['form1'];
    if (!theForm) {
        theForm = document.form1;
    }
    function __doPostBack(eventTarget, eventArgument) {
        if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
            theForm.__EVENTTARGET.value = eventTarget;
            theForm.__EVENTARGUMENT.value = eventArgument;
            theForm.submit();
        }
    }
    //]]>
</script>
<div class="aspNetHidden">
</div>
    <div>
            <script type="text/javascript">
                $(function () {
                    var header = $("#GridView1").find("tr")[0];
                    $("#HeaderDiv").append(header);
                });
</script>
    <style type="text/css">
        .GridViewStyle
        {    
            font-family:Verdana;
            font-size:11px;
            background-color: White; 
        }

        .GridViewHeaderStyle
        {
            font-family:Verdana;
            font-size:15px;
            background-color:#507CD1;
            color:black;
            height:40px;

        }
    </style>

    <br />
          <div>
            <div id="HeaderDiv">
            </div>
            <div id="DataDiv" style="overflow: auto; border: 1px solid olive; width: 2000px; height: 300px;" onscroll="Onscrollfnction();">
    <div>
    <table cellspacing="0" id="GridView1" style="color:#333333;border-collapse:collapse;">
        <tr class="GridViewHeaderStyle">
            <th scope="col">&nbsp;</th><th class="GridViewHeaderStyle" scope="col" style="background-color:#507CD1;"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column1&#39;)" style="color:#333333;"Column1*</a></th><th scope="col"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column2&#39;)" style="color:#333333;">Column2</a></th><th scope="col"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column3&#39;)" style="color:#333333;">Column3</a></th><th scope="col"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column4&#39;)" style="color:#333333;">Column4</a></th><th scope="col"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column5&#39;)" style="color:#333333;">Column5</a></th><th scope="col"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column6&#39;)" style="color:#333333;">Column6</a></th><th scope="col"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column7&#39;)" style="color:#333333;">Column7</a></th><th scope="col"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column8&#39;)" style="color:#333333;">Column8</a></th><th scope="col"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column9&#39;)" style="color:#333333;">Column9</a></th><th scope="col"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column10&#39;)" style="color:#333333;">Column10</a></th><th scope="col"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column11&#39;)" style="color:#333333;">Column11</a></th><th scope="col"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column12&#39;)" style="color:#333333;">Column12</a></th><th scope="col"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column13&#39;)" style="color:#333333;">Column13</a></th><th scope="col"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column14&#39;)" style="color:#333333;">Column14</a></th><th scope="col"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column15&#39;)" style="color:#333333;">Column15</a></th><th scope="col"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column16&#39;)" style="color:#333333;">Column16</a></th><th scope="col"><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Sort$Column17&#39;)" style="color:#333333;">Column 17</a></th><th scope="col">>&nbsp;</th>
        </tr><tr style="background-color:#EFF3FB;">
            <td><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Edit$0&#39;)" style="color:#333333;">Edit</a></td><td>Blah</td><td>Blah</td><td>Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah </td><td>Blah </td><td>Blah </td><td>Blah </td><td>&nbsp;</td><td>Blah </td><td>
                    <span id="GridView1_Label2_0">Blah </span>
                </td><td>Blah </td><td>
                    <span id="GridView1_Label3_0">Blah </span>
                </td><td>
                    <span id="GridView1_Label4_0">Blah </span>
                </td><td>Blah </td><td>
                    <span id="GridView1_Label1_0">Blah </span>
                </td><td>
                    <span id="GridView1_Label5_0">Blah </span>
                </td><td>Blah </td><td>Blah </td><td>&nbsp;</td><td>
                    <span id="GridView1_Label6_0">Blah</span>
                </td><td><a href="javascript:__doPostBack(&#39;GridView1&#39;,&#39;Edit$0&#39;)" style="color:#333333;">Blah </a></td>
        </tr>

    </table>
</div>
                </div>
              </div>
    </div>
    </form>
</body>
</html>

【问题讨论】:

  • 呈现的 HTML 是什么样的?
  • 页面首次加载时完美无缺。来自 Gridview 的数据可以毫无问题地提取,并且 gridview 位于可滚动框内。此外,主题/列标题完美加载。标题看起来美观并且位置完美(保存以快速调整字体大小)。问题是,当您向下滚动 gridview 时,数据以及标题背景颜色会向上滚动,但主题/列标题保持在透明背景的位置。我正在尝试用颜色填充冻结的透明背景。
  • 对,因为 CSS 在客户端上工作,所以我需要查看 HTML,这样我才能看到结构的样子。这会让我知道发生了什么。如果您有示例网址,它将帮助您找到问题。
  • 基本上我将代码分为两部分。代码和围绕它的化妆品。我会用这些信息更新第一篇文章。
  • @afzalulh 抱歉,这是 IE 9。完全没有注意到这一点。我的错。

标签: c# javascript asp.net css datagridview


【解决方案1】:

您的CreateGridHeader 函数中有一行将您想要的背景颜色应用到DataDivObj宽度

DataDivObj.style.width = '50000px';
DataDivObj.style.width = '#507CD1';

这与标题使用的背景颜色相同

.GridViewHeaderStyle
{
    font-family:Verdana;
    font-size:15px;
    position:fixed;

    background-color:#507CD1;
    color:black;
    height:40px;
} 

这里一定有联系。我认为您可以通过将第二个 style.width 更改为 style.backgroundColor 来解决此问题

更新

我现在看到 DataDiv 是一个固定高度,带有溢出:自动。我以前错过了这个。所以你实际上不需要实现滚动功能。

<script type="text/javascript">
    $(function () {
        var header = $("#GridView1").find("tr")[0];
        $("#HeaderDiv").append($("<table id='floatingheader'>").append(header));
    });
</script>

这使它保持在固定高度的 div http://jsfiddle.net/QLWn2/

【讨论】:

  • 我将第二个宽度变量调整为“背景颜色”以及@afzalulh 在他的回答中提供的更改。现在,其中两个标题出现在另一个之上。一个按我的意愿冻结,但第二个包含我在该线程的第一篇文章中首先注意到的相同行为。
  • 嗨,乔,请查看我的第二个答案,它可以解决您的问题
  • 嗨,乔,我已经更新了这个答案。如果它解决了您的问题,请告诉我
  • 不,它没有。我在该线程的第一篇文章末尾(在更新时间戳下方)发布了更新后的渲染 HTML 代码。行为是标题不会冻结。之后一切看起来都很好。
  • 也许我们的电线被交叉了。当你说“冻结”时,你到底是什么意思?您可以链接到另一个站点上所需行为的示例吗?我已经为您提供了一个在固定 div (jsfiddle.net/QLWn2) 之外具有标题的网格示例,以及在页面运行时上下滚动的另一个网格示例 (jsfiddle.net/ezr6k)。我想不出“冻结”标题的任何其他含义
【解决方案2】:

您有两个标头,因为您的 javascript 代码从 GridView 复制标头而不删除它。创建新标题行后,您需要从GridView 中删除原始标题行。

如果我使用您提供的样式而不使用 javascript 创建一个带有 GridView 和一些示例列的空项目,则固定标题有效。当我向上和向下滚动页面时,标题保持在应有的位置。如果这就是你想要的,那么删除 javascript,一切都会正常工作。

但是,我感觉您真正想要的是仅当用户滚动经过GridView 时标题才滚动。也就是说,它应该留在GridView 上,直到浏览器窗口的顶部与GridView 的顶部齐平,然后它应该冻结。

这在 jQuery 中很容易做到,您已经在页面顶部加载了它。这就是你所做的

CSS

.GridViewHeaderStyle
{
    font-family:Verdana;
    font-size:15px;
    background-color:#507CD1;
    color:black;
    height:40px;

}

.floating{
position:fixed;
top: 40px; /* when floated, we need to add the height of the header to its position , as we will have scrolled past it already. */
}

.padded{
margin-top: 40px; /* once the header position is fixed, the gridview will jump up by 40px, so we need to add this class to make sure it stays put */
}

Javascript:

<script type="text/javascript">
    var floating = false;

    $(function () {
        // setup
        // move the header to its own table. simple! 
        var header = $("#<%= GridView1.ClientID %>").find("tr")[0];
        $("#<%= GridView1.ClientID %>").before($("<table id='floatingheader'>").append(header));

        // when scrolling... 
        $(document).scroll(function () {
            // get position of gridview. 
            var gridposition = $("#<%= GridView1.ClientID %>").offset().top; 
            // get scroll height
            var scrollheight = $(document).scrollTop();

            if(!floating && scrollheight > gridposition){
                $("#floatingheader").addClass("floating"); // float the header
                $("#<%= GridView1.ClientID %>").addClass("padded"); // move the gridview down 40px
                floating = true; // set floating flag to true               
            }

            if(floating && scrollheight < gridposition){
                $("#floatingheader").removeClass("floating"); // remove floating class
                $("#<%= GridView1.ClientID %>").removeClass("padded"); // remove padding
                floating = false; // set flag to false
            }
        });
    });
</script>

这将在GridView 上创建一个浮动标题。请注意,如果您在页面顶部有任何浮动菜单,您也需要考虑这些。

【讨论】:

  • 我从代码中删除了 Javascript(包括 div 引用),它只是恢复到正常的 gridview 而不滚动等等。如果我留下 div 引用,那么我会得到与以前相同的行为。滚动时具有透明背景的一个标题。
  • 删除你的javascript代码并用我在这篇文章中给你的jquery替换它,它会工作的。我已经用一个新的 ASP.NET 表单项目对此进行了测试
  • 我得到了与上述相同的结果。
  • 我从一个空白页面重新开始,标题没有浮动,而是随着 gridview 的其余部分向上滚动。
  • 你能分享一下那个新页面的完整代码吗?
【解决方案3】:

注册脚本时,您需要将'GridView1' 替换为'" + GridView1.ClientID + "'。您的方法应如下所示:

protected void Page_Load(object sender, EventArgs e)
{    
    if (GridView1.Rows.Count > 0)
    {
        ClientScript.RegisterStartupScript(this.GetType(), "CreateGridHeader", "<script>CreateGridHeader('DataDiv','" + GridView1.ClientID +  "', 'HeaderDiv');</script>");
    }
}
protected void cmdClick_Click(object sender, EventArgs e)
{
    ClientScript.RegisterStartupScript(this.GetType(), "CreateGridHeader", "<script>CreateGridHeader('DataDiv','" + GridView1.ClientID + "', 'HeaderDiv');</script>");
}

说明:

使用您提供的代码,GridView1 将呈现为MainContent_GridView1。这将导致此行中的 javascript 错误:

Row.className = DataGridObj.rows[0].className;

因此不会将类名分配给新的标题行。因此不会应用任何样式。

【讨论】:

  • 我将此应用到我的代码以及另一个答案中记录的更改。结果在另一个答案中注明。
猜你喜欢
  • 2021-12-11
  • 2012-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-15
  • 2021-02-24
  • 2017-05-22
相关资源
最近更新 更多