【问题标题】:Maintaining page scroll position after updatepanel partial postback更新面板部分回发后保持页面滚动位置
【发布时间】:2014-07-13 06:24:45
【问题描述】:

我是 ASP.NET 的初学者,在部分回发 UpdatePanel 后维护页面的滚动位置时遇到问题。我尝试在<%@ Page Language="C#" ...%> 中设置MaintainScrollPositionOnPostback="true",但没有成功。请注意,我正在使用(并且必须使用)FireFox。

任何帮助将不胜感激。谢谢!这是我的代码:

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<asp:HiddenField ID="ClassificationHiddenField" runat="server" />
<asp:HiddenField ID="DateHiddenField" runat="server" />
<table>
    <tr>
        <td>
            <asp:Panel ID="GroupTitlePanel" CssClass="titlePanelBold" BorderStyle="Ridge" runat="server"
                Width="400px">
                <table id="MainTable">
                    <tr>
                        <td align="center" class="style3">
                            <asp:Label ID="GroupLabel" runat="server">
                            </asp:Label>
                        </td>
                        <td align="center" class="style4">
                            <asp:Label ID="ReturnLabel" runat="server" Text="Expected Return">
                            </asp:Label>
                        </td>
                    </tr>
                </table>
            </asp:Panel>
            <br />
            <asp:Panel ID="GroupMainPanel" runat="server" Width="400px">
            </asp:Panel>
        </td>
        <td width='100px'>
        </td>
        <td>
        </td>
    </tr>
</table>
<asp:Panel ID="BottomPanel" runat="server" BorderStyle="Ridge">
    <table>
        <tr>
            <td align="center">
                <br />
                <asp:ToolkitScriptManager ID="ToolkitScriptManager1" EnablePartialRendering="true"
                    runat="server">
                </asp:ToolkitScriptManager>
                <asp:CheckBoxList runat="server" ID="GroupCheckBoxList" RepeatColumns="10" RepeatDirection="Horizontal"
                    RepeatLayout="Table" AutoPostBack="true" ClientIDMode="AutoID" OnSelectedIndexChanged="GroupCheckBoxList_SelectedIndexChanged">
                </asp:CheckBoxList>
            </td>
        </tr>
        <tr>
            <td>
                <asp:UpdatePanel ID="GroupUpdatePanel" runat="server" Visible="true" UpdateMode="conditional">
                    <ContentTemplate>
                        <asp:Panel ID="GroupGraphPanel" runat="server" Visible="true">
                        </asp:Panel>
                    </ContentTemplate>
                    <Triggers>
                        <asp:AsyncPostBackTrigger ControlID="GroupCheckBoxList" EventName="SelectedIndexChanged" />
                    </Triggers>
                </asp:UpdatePanel>
            </td>
        </tr>
    </table>
</asp:Panel>

【问题讨论】:

  • 您对 jquery 或 javascript 等选项持开放态度吗?或者你希望它完成?
  • 理想情况下没有 jquery 或 javascript(因为我都不熟悉)...
  • 由于 .net 中没有内置解决方案,但您可以使用 javascript 来实现。

标签: c# asp.net scroll updatepanel postback


【解决方案1】:

这看起来像是您问题的答案。作为一个优点;它似乎适用于所有浏览器,而不仅仅是 FF。

http://www.c-sharpcorner.com/Blogs/11804/maintain-scroll-position-on-postback-within-updatepanel.aspx

如果您使用的是 IE,那么它非常简单,只需将代码放入您的 页面指​​令。

<%@ Page Language="C#" AutoEventWireup="true" 
 CodeFile="Default.aspx.cs" Inherits="_Default"
 MaintainScrollPositionOnPostback="true" %> 

但它在 Firefox 中不起作用,因为您必须添加一个浏览器 文件到您的网站

右键单击解决方案资源管理器>添加新项目

选择浏览器文件并将其添加到 App_Browsers 文件夹。

向此浏览器文件添加 MaintainScrollPositionOnPostback 功能 如下所述。

<browsers>
  <browser refID="Mozilla">
      <capabilities>
        <capability name="supportsMaintainScrollPositionOnPostback" value="true" />       
    </capabilities>   
  </browser>
</browsers>

有时这也行不通,

然后一个简单的解决方案就是在网格之后添加一个空白的更新面板 并且 onpostback 只是将焦点放在它将在其中工作的更新面板上 任何浏览器。 在cs postbackevent updatepanel1.Focus();

如果有任何问题,请随时询问或任何修改回复。

【讨论】:

  • 我喜欢最后一个建议,因为它看起来很容易实现。但由于某种原因,即使使用该解决方案,页面也会在部分回发后向上滚动......
  • 他实际上提到有时它不起作用,不推荐第二种解决方案。 Krunal 的解决方案效果最好。
【解决方案2】:

虽然我知道你不熟悉 javascript,但我仍然建议你回答这个问题,因为 .net 中没有内置的解决方案,但你可以使用 javascript 来解决它。别担心 Javascript 并不难,它是 Web 开发的重要组成部分之一。所以就试一试吧。可能会对你有所帮助。

您可以参考这个页面:Maintaining page scroll position after updatepanel partial postback

<form id="form1" runat="server">
  <asp:ScriptManager ID="SM1" runat="server" ScriptMode="Release" />
   <script type="text/javascript">
      // It is important to place this JavaScript code after ScriptManager1
      var xPos, yPos;
      var prm = Sys.WebForms.PageRequestManager.getInstance();

      function BeginRequestHandler(sender, args) {
        if ($get('<%=Panel1.ClientID%>') != null) {
          // Get X and Y positions of scrollbar before the partial postback
          xPos = $get('<%=Panel1.ClientID%>').scrollLeft;
          yPos = $get('<%=Panel1.ClientID%>').scrollTop;
        }
     }

     function EndRequestHandler(sender, args) {
         if ($get('<%=Panel1.ClientID%>') != null) {
           // Set X and Y positions back to the scrollbar
           // after partial postback
           $get('<%=Panel1.ClientID%>').scrollLeft = xPos;
           $get('<%=Panel1.ClientID%>').scrollTop = yPos;
         }
     }

     prm.add_beginRequest(BeginRequestHandler);
     prm.add_endRequest(EndRequestHandler);
 </script>

 <asp:UpdatePanel ID="UpdatePanel1" runat="server">
   <ContentTemplate>
     <asp:Panel ID="Panel1" runat="server" Height="300">
        <%-- Some stuff which would cause a partial postback goes here --%>
     </asp:Panel>
   </ContentTemplate>
 </asp:UpdatePanel>

【讨论】:

  • 克鲁纳尔,谢谢!但是如果我的页面是内容页面,我应该在哪里放置脚本?我应该把它放在母版页吗?如果是这样,究竟在哪里(顶部,底部,...)?另外,如果我使用的是 ToolScriptManager,是否将脚本放在它之前/之后?
  • 您使用的是.net 的哪个框架?差别不是很大,最好避免使用 ToolkitScriptManager。主要原因是使用标准的 CompositeScript 功能,您可以更好地控制脚本的组合方式,并可以优化页面的呈现。 ScriptManager 和 ToolScriptManager 的区别可以参考这个*.com/questions/6348589/…
【解决方案3】:

您可以将焦点设置在您希望在屏幕上看到的控件上。

例如,如果下拉列表“ddlCity”是导致回发的控件,则在下拉列表 SelectedIndexChanged 代码之后执行以下操作:

ddlCity.Focus();

【讨论】:

    【解决方案4】:

    我能够通过以下 hack 解决类似的问题:

    将 HiddenField 控件添加到您正在使用的页面或控件中。确保将 ClientIDMode 设置为静态,以便在 JavaScript 中轻松访问它。我们将使用 JavaScript 来更新这个控件:

    <asp:HiddenField ID="scrollPosition" ClientIDMode="Static" runat="server" /> 
    

    还添加一个面板控件作为我们将插入一些 javascript 的目标:

    <asp:Panel ID="pnlScriptRunner" runat="server"></asp:Panel>
    

    添加以下 JavaScript。使用 window.onscroll 函数,我们正在更新我们的 HiddenField 控件。 updateScrollPosition 函数将从我们后面的 C# 代码中调用:

    <script> 
         window.onscroll = function () {
              var ctrl = document.getElementById("scrollPosition");
              ctrl.value = document.body.scrollTop;
              console.log(ctrl.value);
         };
    
         function updateScrollPosition(value) {       
             window.scrollTo(0, value);
             console.log("updating scroll position");
         }
    </script> 
    

    创建一个新的 C# 类并添加以下方法。这将允许我们从 C# 的代码隐藏中插入一些 Javascript:

    public static class ClientScript
    {
        public static void InsertScript(string script, Control target)
        {
            HtmlGenericControl s = new HtmlGenericControl();
            s.TagName = "script";
            s.InnerHtml = script;
            target.Controls.Add(s); 
        }        
    }
    

    现在,在您的控件或页面背后的代码中,使用我们创建的静态类将 javascript 插入到 pnlScriptRunner 中,使用来自 ASP.NET HiddenField 控件的值调用 JavaScript 函数“updateScrollPosition(value)”:

        protected void btnRotate_Click(object sender, EventArgs e)
        {
             //Do stuff with controls in your update panel here, then: 
             ClientScript.InsertScript("updateScrollPosition(" + scrollPosition.Value + ");", pnlScriptRunner);
             UpdatePanel1.Update();
    
        }
    

    我的 btnRotate_Click 事件在更新面板中注册为触发器:

    <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
         <ContentTemplate>
             <b>Image Preview: </b><br />
             <asp:Image ID="img" runat="server" CssClass="profileImage" />
             <br /> 
             <br />
             <asp:Button ID="btnRotate" runat="server" Text="Rotate Image" ClientIDMode="Static" OnClick="btnRotate_Click" />
             <br />
             <br />
          </ContentTemplate>
          <Triggers>
               <asp:PostBackTrigger ControlID="btnRotate" />
          </Triggers>
    </asp:UpdatePanel>
    

    以下参考资料是必要的:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;
    

    希望这会有所帮助!

    【讨论】: