我有一个包含在可滚动 div 中的 GridView。我还有一个按钮,它根据页面上文本框的文本选择此 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" />
 
<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>
 
<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++;
}
}
}
}
有人可以解释为什么它没有按预期工作吗?
一些 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++;
}
}
}
}
希望这有帮助。
deostroll,我正在使用 Internet Explorer。 rows[rowIndex].tagName 属性似乎为 null,因为无法显示。这是我修改后的代码:
.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" />
 
<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>
 
<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++;
}
}
}
}
我现在可以正常工作了。这是我更正后的代码:
.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" />
 
<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>
 
<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”。