【问题标题】:ASP.NET GridView within Scrollable Div: Scroll to SelectedIndex可滚动 Div 中的 ASP.NET GridView:滚动到 SelectedIndex
【发布时间】:2013-07-07 21:06:50
【问题描述】:

我有一个 GridView 包含在一个可滚动的 div 中。我还有一个 Button,它根据页面上 TextBox 的文本在此 GirdView 中选择一行。该行选择得很好,但我无法让 div 以编程方式滚动到选定的行。我尝试了多种涉及 JavaScript 的“scrollTop”方法的方法,但由于某种原因,我无法让它们正常工作。到目前为止,这是我的代码(“btnGo_OnClick”方法的一些代码取自对 asp.net 论坛上类似问题的回答,但它似乎对我不起作用):

.aspx 文件:

<%@ Page Title="" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true"
CodeBehind="StudentList.aspx.cs" Inherits="WebApplication1.WebForm1" %>

<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <br />
    <div style="overflow: scroll; height: 400px;">
        <asp:GridView ID="StudentList" runat="server" AutoGenerateColumns="False" DataSourceID="DataSource1"
            AllowSorting="true" CellPadding="4" DataKeyNames="Email">
            <Columns>
                <asp:BoundField DataField="LastName" HeaderText="Last" ReadOnly="True" SortExpression="LastName" />
                <asp:BoundField DataField="FirstName" HeaderText="First" ReadOnly="True" SortExpression="FirstName" />
                <asp:BoundField DataField="MiddleInitial" HeaderText="Middle" ReadOnly="True" SortExpression="MiddleInitial" />
                <asp:BoundField DataField="Phone" HeaderText="Phone" ReadOnly="True" SortExpression="Phone" />
                <asp:BoundField DataField="Email" HeaderText="Email" ReadOnly="True" SortExpression="Email" />
                <asp:BoundField DataField="GPA" HeaderText="GPA" ReadOnly="True" SortExpression="GPA" />
                <asp:TemplateField HeaderText="">
                    <ItemTemplate>
                        <asp:Button ID="btnEdit1" Text="Edit" AutoPostBack="True" runat="server" OnClick="btnEdit1_OnClick" />
                        &nbsp
                        <asp:Button ID="btnDelete" Text="Delete" AutoPostBack="True" runat="server" OnClick="btnDelete_OnClick" />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
            <SelectedRowStyle BackColor="Black" ForeColor="White" />
        </asp:GridView>
    </div>
    <br />
    <br />
    Search by Last Name:
    <asp:TextBox ID="txtSearch" runat="server"></asp:TextBox>
    &nbsp
    <asp:Button ID="btnGo" Text="Go" AutoPostBack="True" runat="server" OnClick="btnGo_OnClick" />
    <br />
    <br />
    <asp:Label ID="lbl1" runat="server" Text=""></asp:Label>
    <asp:AccessDataSource ID="DataSource1" runat="server" DataFile="~/App_Data/University(2).accdb"
        SelectCommand="SELECT [LastName], [FirstName], [MiddleInitial], [Phone], [Email], [GPA] 
FROM [Students] ORDER BY [LastName]" DeleteCommand=""></asp:AccessDataSource>
</asp:Content>

还有 .aspx.cs 文件:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;

namespace WebApplication1
{
    public partial class WebForm1 : System.Web.UI.Page
    {

        protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected void btnDelete_OnClick(object sender, EventArgs e)
        {
            Button b = (Button)sender;
            GridViewRow containingRow = (GridViewRow)b.NamingContainer;
            String strEmail = containingRow.Cells[4].Text;
            DataSource1.DeleteCommand = "DELETE FROM [CoursesTaken] WHERE [StudentID] = '" + strEmail + "'";
            DataSource1.Delete();
            DataSource1.DeleteCommand = "DELETE FROM [Students] WHERE [Email] = '" + strEmail + "'";
            DataSource1.Delete();
            StudentList.DataBind();
        }

        protected void btnEdit1_OnClick(object sender, EventArgs e)
        {
            Button b = (Button)sender;
            GridViewRow containingRow = (GridViewRow)b.NamingContainer;
            Session["Email"] = containingRow.Cells[4].Text;
            Response.Redirect("~/StudentEdit.aspx");
        }

        protected void btnGo_OnClick(object sender, EventArgs e)
        {
            int i = 0;
            foreach (GridViewRow rowItem in StudentList.Rows)
            {
                if (rowItem.Cells[0].Text.StartsWith(txtSearch.Text))
                {
                    StudentList.SelectedIndex = i;
                int intScrollTo = this.StudentList.SelectedIndex * (int)this.StudentList.RowStyle.Height.Value;
                    string strScript = "";
                    strScript += "var gridView = document.getElementById('" + this.StudentList.ClientID + "');\n";
                    strScript += "if (gridView != null && gridView.parentElement != null && gridView.parentElement.parentElement != null)\n";
                    strScript += "  gridView.parentElement.parentElement.scrollTop = " + intScrollTo + ";\n";
                    ScriptManager.RegisterClientScriptBlock(this.Page, this.GetType(), "btnGo_OnClick", strScript, true);
                    break;
                }
                i++;
            }
        }
    }

}

有人可以解释为什么它没有按预期工作吗?

【问题讨论】:

    标签: asp.net html gridview scrolltop selectedindex


    【解决方案1】:

    一些 javascript 可以提供帮助。看看下面的帖子:https://stackoverflow.com/a/4558637/145682

    这是一个 POC:

    标记:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GridViewScrollIndex.Default" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
        <style type="text/css">
            #form1
            {
                height: 225px;
            }
        </style>
        <script>
            function focusRow(id, rowIndex) {
                var tbl = document.getElementById(id);
                var rows = tbl.childNodes[0].childNodes;
                rows[rowIndex].childNodes[0].focus();
                document.getElementById('console').innerText = rows[rowIndex].childNodes[0].innerHTML;
            }
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
        <div style="padding:10px; background-color:lightblue; height:105px; overflow:scroll;">
            <asp:GridView ID="GridView1" runat="server">
                <SelectedRowStyle BackColor="Yellow" />
            </asp:GridView>
        </div>
        <div>
            <asp:DropDownList ID="ddlSelectIndexes" runat="server"></asp:DropDownList>
            <asp:Button ID="btnSelect" runat="server" Text="Select" OnClick="btnSelect_Click" />
            <div id="console"></div>
        </div>
        </form>
    </body>
    </html>
    

    代码背后:

    using System;
    using System.Linq;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace GridViewScrollIndex
    {
        public partial class Default : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                if (!IsPostBack)
                {
                    var arr = Enumerable.Range(1, 100);
                    GridView1.DataSource = arr;
                    GridView1.DataBind();
                    ddlSelectIndexes.DataSource = arr.Select(x=> new {f1=x, f2=x});
                    ddlSelectIndexes.DataValueField = "f1";
                    ddlSelectIndexes.DataTextField = "f2";
                    ddlSelectIndexes.DataBind();
                }
            }
    
            protected void btnSelect_Click(object sender, EventArgs e)
            {
                string selVal = ddlSelectIndexes.SelectedValue;
                int i=0;
                foreach (GridViewRow row in GridView1.Rows)
                {
                    if (row.RowType == DataControlRowType.DataRow)
                    {                    
                        if (row.Cells[0].Text == selVal)
                        {
                            GridView1.SelectedIndex = i;
                            ScriptManager.RegisterStartupScript(GridView1, this.GetType(), "highlight",
                                string.Format("window.onload = function() {2} focusRow('{0}', {1}); {3};", GridView1.ClientID, i+1, "{", "}"), true);
                            break;
                        }                    
                    }
                    i++;
                }
            }
        }
    }
    

    希望这会有所帮助。

    【讨论】:

    • 我会将您的想法改编为我的代码并报告它是否成功。
    • 调试此示例会出现以下错误:“Microsoft JScript 运行时错误:无法获取属性 'childNodes' 的值:对象为 null 或未定义”,用于标记页面中脚本的以下行:“行[rowIndex].childNodes[0].focus();”。这是为什么呢?
    • 您可能得到了错误的参考。但是,我必须查看您改编的代码才能确定。放入一些网站,如pastebin。你使用的是什么浏览器?在您的调试器中尝试让我知道以下输出:rows[rowIndex].tagName
    • 我修改后的代码已上传,作为此问题的答案,以及有关我的浏览器的详细信息和您询问的值。
    • @ScottRobertLane 您使用的是什么版本的 IE?在 js 函数中,您的目标应该是查找 tr 及其嵌套的 td 元素,该元素对应于作为参数传递给函数的 rowIndex 值。因此,您分配给 childNodes 属性的下标可能会有所不同……您必须调试并找出这一点
    【解决方案2】:

    deostroll,我正在使用 Internet Explorer。 rows[rowIndex].tagName 属性似乎为空,因为它无法显示。这是我修改后的代码:

    .aspx 文件:

    <%@ Page Title="" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true"
        CodeBehind="StudentList.aspx.cs" Inherits="WebApplication1.WebForm1" %>
    
    <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
        <script>
            function focusRow(id, rowIndex) {
                var tbl = document.getElementById(id);
                var rows = tbl.childNodes[0].childNodes;
                alert(rows[rowIndex].tagName);
                rows[rowIndex].childNodes[0].focus();
            }
        </script>
        <br />
        <div style="overflow: scroll; height: 400px;">
            <asp:GridView ID="StudentList" runat="server" AutoGenerateColumns="False" DataSourceID="DataSource1"
                AllowSorting="true" CellPadding="4" DataKeyNames="Email">
                <Columns>
                    <asp:BoundField DataField="LastName" HeaderText="Last" ReadOnly="True" SortExpression="LastName" />
                    <asp:BoundField DataField="FirstName" HeaderText="First" ReadOnly="True" SortExpression="FirstName" />
                    <asp:BoundField DataField="MiddleInitial" HeaderText="Middle" ReadOnly="True" SortExpression="MiddleInitial" />
                    <asp:BoundField DataField="Phone" HeaderText="Phone" ReadOnly="True" SortExpression="Phone" />
                    <asp:BoundField DataField="Email" HeaderText="Email" ReadOnly="True" SortExpression="Email" />
                    <asp:BoundField DataField="GPA" HeaderText="GPA" ReadOnly="True" SortExpression="GPA" />
                    <asp:TemplateField HeaderText="">
                        <ItemTemplate>
                            <asp:Button ID="btnEdit1" Text="Edit" AutoPostBack="True" runat="server" OnClick="btnEdit1_OnClick" />
                            &nbsp
                            <asp:Button ID="btnDelete" Text="Delete" AutoPostBack="True" runat="server" OnClick="btnDelete_OnClick" />
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
                <SelectedRowStyle BackColor="Black" ForeColor="White" />
            </asp:GridView>
        </div>
        <br />
        <br />
        Search by Last Name:
        <asp:TextBox ID="txtSearch" runat="server"></asp:TextBox>
        &nbsp
        <asp:Button ID="btnGo" Text="Go" AutoPostBack="True" runat="server" OnClick="btnGo_OnClick" />
        <br />
        <br />
        <asp:Label ID="lbl1" runat="server" Text=""></asp:Label>
        <asp:AccessDataSource ID="DataSource1" runat="server" DataFile="~/App_Data/University(2).accdb"
            SelectCommand="SELECT [LastName], [FirstName], [MiddleInitial], [Phone], [Email], [GPA] 
    FROM [Students] ORDER BY [LastName]" DeleteCommand=""></asp:AccessDataSource>
    </asp:Content>
    

    .aspx.cs 文件:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Text.RegularExpressions;
    
    namespace WebApplication1
    {
        public partial class WebForm1 : System.Web.UI.Page
        {
    
            protected void Page_Load(object sender, EventArgs e)
            {
            }
    
            protected void btnDelete_OnClick(object sender, EventArgs e)
            {
                Button b = (Button)sender;
                GridViewRow containingRow = (GridViewRow)b.NamingContainer;
                String strEmail = containingRow.Cells[4].Text;
                DataSource1.DeleteCommand = "DELETE FROM [CoursesTaken] WHERE [StudentID] = '" + strEmail + "'";
                DataSource1.Delete();
                DataSource1.DeleteCommand = "DELETE FROM [Students] WHERE [Email] = '" + strEmail + "'";
                DataSource1.Delete();
                StudentList.DataBind();
            }
    
            protected void btnEdit1_OnClick(object sender, EventArgs e)
            {
                Button b = (Button)sender;
                GridViewRow containingRow = (GridViewRow)b.NamingContainer;
                Session["Email"] = containingRow.Cells[4].Text;
                Response.Redirect("~/StudentEdit.aspx");
            }
    
            protected void btnGo_OnClick(object sender, EventArgs e)
            {
                int i = 0;
                foreach (GridViewRow rowItem in StudentList.Rows)
                {
                    if (rowItem.Cells[0].Text.ToUpper().StartsWith(txtSearch.Text.ToUpper()))
                    {
                        StudentList.SelectedIndex = i;
                        ScriptManager.RegisterStartupScript(StudentList, this.GetType(), "highlight",
                        string.Format("window.onload = function() {2} focusRow('{0}', {1}); {3};", StudentList.ClientID, i + 1, "{", "}"), true);
                        break;
                    }
                    i++;
                }
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      我现在可以正常工作了。这是我更正的代码:

      .aspx 文件:

      <%@ Page Title="" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true"
          CodeBehind="StudentList.aspx.cs" Inherits="WebApplication1.WebForm1" %>
      
      <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
          <script>
              function focusRow(id, pxlAmount) {
                  var tbl = document.getElementById(id);
                  dTbl = tbl.parentElement.parentElement;
                  dTbl.scrollTop = pxlAmount;
              }
          </script>
          <br />
          <div style="overflow: scroll; height: 400px;">
              <asp:GridView ID="StudentList" runat="server" AutoGenerateColumns="False" DataSourceID="DataSource1"
                  AllowSorting="true" CellPadding="4" DataKeyNames="Email" RowStyle-Height="40px">
                  <Columns>
                      <asp:BoundField DataField="LastName" HeaderText="Last" ReadOnly="True" SortExpression="LastName" />
                      <asp:BoundField DataField="FirstName" HeaderText="First" ReadOnly="True" SortExpression="FirstName" />
                      <asp:BoundField DataField="MiddleInitial" HeaderText="Middle" ReadOnly="True" SortExpression="MiddleInitial" />
                      <asp:BoundField DataField="Phone" HeaderText="Phone" ReadOnly="True" SortExpression="Phone" />
                      <asp:BoundField DataField="Email" HeaderText="Email" ReadOnly="True" SortExpression="Email" />
                      <asp:BoundField DataField="GPA" HeaderText="GPA" ReadOnly="True" SortExpression="GPA" />
                      <asp:TemplateField HeaderText="">
                          <ItemTemplate>
                              <asp:Button ID="btnEdit1" Text="Edit" AutoPostBack="True" runat="server" OnClick="btnEdit1_OnClick" />
                              &nbsp
                              <asp:Button ID="btnDelete" Text="Delete" AutoPostBack="True" runat="server" OnClick="btnDelete_OnClick" />
                          </ItemTemplate>
                      </asp:TemplateField>
                  </Columns>
                  <SelectedRowStyle BackColor="Black" ForeColor="White" />
              </asp:GridView>
          </div>
          <br />
          <br />
          Search by Last Name:
          <asp:TextBox ID="txtSearch" runat="server"></asp:TextBox>
          &nbsp
          <asp:Button ID="btnGo" Text="Go" AutoPostBack="True" runat="server" OnClick="btnGo_OnClick" />
          <br />
          <br />
          <asp:Label ID="lbl1" runat="server" Text=""></asp:Label>
          <asp:AccessDataSource ID="DataSource1" runat="server" DataFile="~/App_Data/University(2).accdb"
              SelectCommand="SELECT [LastName], [FirstName], [MiddleInitial], [Phone], [Email], [GPA] 
      FROM [Students] ORDER BY [LastName]" DeleteCommand=""></asp:AccessDataSource>
      </asp:Content>
      

      .aspx.cs 文件:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Web;
      using System.Web.UI;
      using System.Web.UI.WebControls;
      using System.Text.RegularExpressions;
      
      namespace WebApplication1
      {
          public partial class WebForm1 : System.Web.UI.Page
          {
      
              protected void Page_Load(object sender, EventArgs e)
              {
              }
      
              protected void btnDelete_OnClick(object sender, EventArgs e)
              {
                  Button b = (Button)sender;
                  GridViewRow containingRow = (GridViewRow)b.NamingContainer;
                  String strEmail = containingRow.Cells[4].Text;
                  DataSource1.DeleteCommand = "DELETE FROM [CoursesTaken] WHERE [StudentID] = '" + strEmail + "'";
                  DataSource1.Delete();
                  DataSource1.DeleteCommand = "DELETE FROM [Students] WHERE [Email] = '" + strEmail + "'";
                  DataSource1.Delete();
                  StudentList.DataBind();
              }
      
              protected void btnEdit1_OnClick(object sender, EventArgs e)
              {
                  Button b = (Button)sender;
                  GridViewRow containingRow = (GridViewRow)b.NamingContainer;
                  Session["Email"] = containingRow.Cells[4].Text;
                  Response.Redirect("~/StudentEdit.aspx");
              }
      
              protected void btnGo_OnClick(object sender, EventArgs e)
              {
                  int i = 0;
                  foreach (GridViewRow rowItem in StudentList.Rows)
                  {
                      if (rowItem.Cells[0].Text.ToUpper().StartsWith(txtSearch.Text.ToUpper()))
                      {
                          StudentList.SelectedIndex = i;
                          int iScrollTo = (StudentList.SelectedIndex) * ((int)StudentList.RowStyle.Height.Value); /* RowStyle.Height must be explicitly defined in the opening tag of the GridView */
                          ScriptManager.RegisterStartupScript(StudentList, this.GetType(), "highlight",
                          string.Format("window.onload = function() {2} focusRow('{0}', {1}); {3};", StudentList.ClientID, iScrollTo, "{", "}"), true);
                          break;
                      }
                      i++;
                  }
              }
          }
      }
      

      问题最终变得很简单:我没有在开始标记中明确定义 GridView 的 RowStyle.Height 属性。因此,在计算要在 div 中滚动到的位置期间,这被评估为“0”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-07
        相关资源
        最近更新 更多