C# 在更新面板的列表框中保持滚动位置,而不是页面
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/543131/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Maintain scroll position in listboxes in updatepanels, NOT the page
提问by Xaisoft
I have a listbox inside an update panel. When I scroll down and select an item, it scrolls back to the top of the listbox. I heard that the dom does not keep track of the scroll position on a postback. Does anyone have a solution/example on how to solve this?
我在更新面板中有一个列表框。当我向下滚动并选择一个项目时,它会滚动回列表框的顶部。我听说 dom 不跟踪回发时的滚动位置。有没有人有关于如何解决这个问题的解决方案/示例?
Thanks, XaiSoft
谢谢,XaiSoft
采纳答案by Chris Zwiryk
You're running into this problem because the UpdatePanel
completely replaces your scrolled <select>
element with a new one when the asynchronous request comes back.
您遇到了这个问题,因为当异步请求返回时,它会用一个新元素UpdatePanel
完全替换您的滚动<select>
元素。
Possible solutions:
可能的解决方案:
Use JavaScript to store the
scrollTop
property of the<select>
element in a hidden form element before theUpdatePanel
is submitted (by calling theClientScriptManager.RegisterOnSubmitStatement
method) and then setting it on the new<select>
when the AJAX call comes back. This will be tedious, error-prone, and probably not very compatible (see here).Use JavaScript to store the
<select>
'sselectedIndex
property and re-select that item when the AJAX call comes back. Obviously this won't work if the user hasn't selected anything yet.Don't use
UpdatePanel
s. Try jQuery+ ASP.NET page methodsinstead.
使用 JavaScript在提交之前(通过调用该方法)
scrollTop
将<select>
元素的属性存储在隐藏的表单元素中,然后在 AJAX 调用返回时将其设置在新元素上。这将是乏味的、容易出错的,并且可能不太兼容(请参阅此处)。UpdatePanel
ClientScriptManager.RegisterOnSubmitStatement
<select>
使用 JavaScript 存储
<select>
的selectedIndex
属性并在 AJAX 调用返回时重新选择该项目。显然,如果用户还没有选择任何东西,这将不起作用。
回答by Ole Lynge
It seems that the following code example scrolls in the following way:
下面的代码示例似乎按以下方式滚动:
Internet Explorer 8: After postback the selected item is the first visible item.
Firefox: After postback the selected item is always visible (but might be the last visible item).
Chrome: After postback, the selected item might be hidden since the listbox scrolls to the top, as you say.
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>
回答by Veerendranath Darsi
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*****
//Maintain Scroll Position for Panel/Div with out Update 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
回答by atconway
You can still achieve the partial postback using the UpdatePanel
containing a ListBox
, but prevent it from being overwritten by a new instance by setting the following on the UpdatePanel
:
您仍然可以使用UpdatePanel
包含 a实现部分回发ListBox
,但通过在 上设置以下内容来防止它被新实例覆盖UpdatePanel
:
ChildrenAsTriggers="False"
This as stated in the MSDN:
这如MSDN中所述:
Gets or sets a value that indicates whether postbacks from immediate child controls of an UpdatePanel control update the panel's content. Set the ChildrenAsTriggers property to false if do NOT you want postbacks from immediate child controls of the UpdatePanel control to cause an update of the panel's content.
获取或设置一个值,该值指示来自 UpdatePanel 控件的直接子控件的回发是否更新面板的内容。如果您不希望 UpdatePanel 控件的直接子控件的回发导致面板内容的更新,请将 ChildrenAsTriggers 属性设置为 false。
The one caveat to this is if you are trying to do any other visual manipulation to the ListBox from the server-side (i.e. adding CSS
attributes to the items on postbacks), then you will not see them render until another unrelated postback occurs. If all you are doing is making selections than setting ChildrenAsTriggers="False"
will work.
对此的一个警告是,如果您尝试从服务器端对 ListBox 进行任何其他可视化操作(即CSS
在回发时向项目添加属性),那么您将不会看到它们呈现,直到发生另一个不相关的回发。如果您所做的只是进行选择,则设置ChildrenAsTriggers="False"
将起作用。
回答by narayan
For the enterprise application I was working on, it turned out that the MasterPage.Master page was handling the Sys.WebForms.PageRequestManager.getInstance().add_endRequest event and setting window.scroll(0,0) within it. The content pages were obviously executing the window.scroll(0,0) on each trigger of the contentpage's UpdatePanel. I tried overriding the add_endRequest functionality in the content page but could not get that to work. Eventually I just modified the Master.Master to not do window.scroll(0,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)。