在updatepanel中的列表框中维护滚动位置,而不是页面

时间:2009-02-12 20:39:12

标签: c# asp.net listbox

我在更新面板中有一个列表框。当我向下滚动并选择一个项目时,它会滚动回列表框的顶部。我听说dom没有跟踪回发上的滚动位置。有没有人有解决方法/示例如何解决这个问题?

谢谢, XaiSoft

5 个答案:

答案 0 :(得分:7)

您遇到了这个问题,因为当异步请求返回时,UpdatePanel完全用新的元素替换滚动的<select>元素。

可能的解决方案:

  1. 在提交scrollTop之前,使用JavaScript将<select>元素的UpdatePanel属性存储在隐藏的表单元素中(通过调用ClientScriptManager.RegisterOnSubmitStatement方法)然后在AJAX调用返回时将其设置在新的<select>上。这将是乏味的,容易出错,并且可能不太兼容(参见here)。

  2. 使用JavaScript存储<select>的{​​{1}}属性,并在AJAX调用返回时重新选择该项。显然,如果用户尚未选择任何内容,这将无效。

  3. <强> Don't use UpdatePanels 即可。请改为jQuery + ASP.NET page methods

答案 1 :(得分:4)

    var xPos, yPos;
    var prm = Sys.WebForms.PageRequestManager.getInstance();

    function BeginRequestHandler(sender, args) {
        if (($get('Panel1')) != null) {
            xPos = $get('Panel1').scrollLeft;
            yPos = $get('Panel1').scrollTop;
        }
    }

    function EndRequestHandler(sender, args) {
        if (($get('Panel1')) != null) {
            $get('Panel1').scrollLeft = xPos;
            $get('Panel1').scrollTop = yPos;
        }
    }
    prm.add_beginRequest(BeginRequestHandler);
    prm.add_endRequest(EndRequestHandler);

    //Note: "Panel1" Panel or div u want to maintain scroll position
    //Note: This Java Script should be added after Scriptmanager*****

//使用“更新”面板

维护Panel / Div的滚动位置
    window.onload = function() {
        var strCook = document.cookie;
        if (strCook.indexOf("!~") != 0) {
            var intS = strCook.indexOf("!~");
            var intE = strCook.indexOf("~!");
            var strPos = strCook.substring(intS + 2, intE);
            document.getElementById('Panel1').scrollTop = strPos;
        }
    }
    function SetDivPosition() {
        var intY = document.getElementById('Panel1').scrollTop;
        document.title = intY;
        document.cookie = "yPos=!~" + intY + "~!";
    }


   //Note: "Panel1" Panel id or div id for which u want to maintain scroll position

答案 2 :(得分:0)

以下代码示例似乎以下列方式滚动:

  • Internet Explorer 8:回发后,所选项目是第一个可见项目。

  • Firefox:回发后,所选项目始终可见(但可能是最后一个可见项目)。

  • Chrome:回发后,可能会隐藏所选项目,因为列表框会滚动到顶部,如您所说。

<asp:UpdatePanel ID="up1" runat="server">
    <ContentTemplate>
        <asp:ListBox ID="lb1" runat="server" Height="100px" AutoPostBack="true">
            <asp:ListItem>A</asp:ListItem>
            <asp:ListItem>B</asp:ListItem>
            <asp:ListItem>C</asp:ListItem>
            <asp:ListItem>D</asp:ListItem>
            <asp:ListItem>E</asp:ListItem>
            <asp:ListItem>F</asp:ListItem>
            <asp:ListItem>G</asp:ListItem>
            <asp:ListItem>H</asp:ListItem>
        </asp:ListBox>
    </ContentTemplate>
</asp:UpdatePanel>

答案 3 :(得分:0)

您仍然可以使用包含UpdatePanel的{​​{1}}来实现部分回发,但可以通过在ListBox上设置以下内容来阻止它被新实例覆盖:

UpdatePanel

MSDN中所述:

  

获取或设置一个值,该值指示是否从立即回发   UpdatePanel控件的子控件更新面板的内容。   如果不需要,将ChildrenAsTriggers属性设置为false   从UpdatePanel控件的直接子控件回发到   导致更新面板的内容。

对此的一个警告是,如果您尝试从服务器端对ListBox进行任何其他视觉操作(即将ChildrenAsTriggers="False" 属性添加到回发上的项目),那么您将看不到它们呈现直到发生另一个不相关的回发。如果您所做的只是进行选择,那么设置CSS将起作用。

答案 4 :(得分:0)

对于我正在处理的企业应用程序,事实证明MasterPage.Master页面正在处理Sys.WebForms.PageRequestManager.getInstance()。add_endRequest事件并在其中设置window.scroll(0,0)。内容页面显然在内容页面的UpdatePanel的每个触发器上执行window.scroll(0,0)。我尝试覆盖内容页面中的add_endRequest功能,但无法使其工作。最后我只是修改了Master.Master而没做window.scroll(0,0)。