2009-04-14 64 views
8

我在页面中获得了特别大的表单。当表单被验证并且一个字段无效时,我想将窗口滚动到该控件。调用控件的Focus()似乎并不这样做。我找到了一种JavaScript解决方法将窗口滚动到控件,但是ASP.NET中是否有内置的内容?ASP.NET:滚动控制

回答

2

添加MaintainScrollPositionOnPostback是ASP.NET有建于最接近的,但不一定会跳转到无效的字段(一个或多个)。

<%@ Page MaintainScrollPositionOnPostback="true" %> 
+1

这不是他所描述的 - 他希望页面跳转到未通过验证的表单部分,而不一定是用户上次的位置。 – 2009-04-14 02:08:54

+1

它没有回答这个问题,但他确实解决了我的问题。谢谢! – 2009-12-01 21:06:34

1

你确定Focus()不会做你所描述的吗?在底层,它实质上是在做“JavaScript解决方法” - 它将一些JS写入页面,该页面使用匹配的ID调用控件上的focus():

Focus()在页面完成之前调用的最后一个控件处理将其写入页面:

<script type="text/javascript"> 
//<![CDATA[ 
WebForm_AutoFocus('txtFocus2');//]]> 
</script> 
0

我使用基本的HTML fragments实现了类似的功能。你只是离开元素具有与已知ID:

<span id="CONTROL-ID"></span> 

,然后要么通过脚本,在服务器端更改URL:

window.location += "#CONTROL-ID"; 

在页面不会重新加载第一种情况下,它会向下滚动到控件。

5

所以我相信问题是因为我试图专注于HtmlGenericControls而不是WebControls。

我刚刚结束了做基于关闭的解决方法:

http://ryanfarley.com/blog/archive/2004/12/21/1325.aspx http://www.codeproject.com/KB/aspnet/ViewControl.aspx

......在时间的兴趣。

public static void ScrollTo(this HtmlGenericControl control) 
{ 
    control.Page.RegisterClientScriptBlock("ScrollTo", string.Format(@" 

     <script type='text/javascript'> 

      $(document).ready(function() {{ 
       var element = document.getElementById('{0}'); 
       element.scrollIntoView(); 
       element.focus(); 
      }}); 

     </script> 

    ", control.ClientID)); 
} 

用法:

if (!this.PropertyForm.Validate()) 
{ 
    this.PropertyForm.ErrorMessage.ScrollTo(); 
    failed = true; 
} 

(尽管似乎Page.RegisterClientScriptBlock()已被弃用用于Page.ClientScript.RegisterClientScriptBlock())。

5

您是否在页面上使用验证摘要?

如果是这样,那么ASP.NET renders some javascript to automatically scroll to the top of the page可能会覆盖客户端验证的自动行为以关注最后一个无效控件。

另外,你有没有关闭客户端验证?

如果你在客户端验证产生的JavaScript来看看你会看到这样的方法:

function ValidatorValidate(val, validationGroup, event) { 
    val.isvalid = true; 
    if ((typeof(val.enabled) == "undefined" || val.enabled != false) && 
     IsValidationGroupMatch(val, validationGroup)) { 
    if (typeof(val.evaluationfunction) == "function") { 
     val.isvalid = val.evaluationfunction(val); 
     if (!val.isvalid && Page_InvalidControlToBeFocused == null && 
      typeof(val.focusOnError) == "string" && val.focusOnError == "t") { 
     ValidatorSetFocus(val, event); 
     } 
    } 
    } 
    ValidatorUpdateDisplay(val); 
} 

注意调用ValidatorSetFocus,这是一种试图将焦点设置一个相当长的方法有问题的控制,或者如果你有多个错误,这是有效的,使用(最终)以下行的最后控制:

if (typeof(ctrl.focus) != "undefined" && ctrl.focus != null) { 
    ctrl.focus(); 
    Page_InvalidControlToBeFocused = ctrl; 
} 

要获得这种行为的工作,你会非常需要确保所有的验证器都被设置o是客户端 - 服务器端验证器显然需要回发,这可能会影响事物(即失去焦点/位置) - 并将MaintainScrollPositionOnPostBack设置为true可能会导致页面重新加载到提交按钮,而不是无效的表单元素。

使用服务器端.Focus方法将导致ASP.NET呈现出一些javascript“在页面加载”(即接近页面底部),但这可能被上面讨论的其他机制之一重写。

2

很简单的解决方法是设置(取其或者您正在使用验证器控制)的RequiredFieldValidator的SetFocusOnError属性为true

+0

http://weblogs.asp.net/dfindley/archive/2007/06/29/a-quick-fix-for-the-validator-setfocusonerror-bug.aspx – softwaredeveloper 2011-08-12 12:55:09

0

将以下JavaScript:

function ScrollToFirstError() { 
     Page_ClientValidate(); 
     if (Page_IsValid == false) { 
      var topMostValidator; 
      var lastOffsetTop; 
      for (var i = 0; i < Page_Validators.length; i++) { 
       var vld = Page_Validators[i]; 
       if (vld.isvalid == false) { 
        if (PageOffset(vld) < lastOffsetTop || lastOffsetTop == undefined) { 
         topMostValidator = vld; 
         lastOffsetTop = vld.offsetTop; 
        } 
       } 
      } 
      topMostValidator.scrollIntoView(); 
     } 
     return Page_IsValid; 
    } 

    function PageOffset(theElement) { 
     var selectedPosY = 0; 
     while (theElement != null) { 
      selectedPosY += theElement.offsetTop; 
      theElement = theElement.offsetParent; 
     } 
     return selectedPosY; 
    } 

然后在调用ScrollToFirstError()你OnClientClick正在保存的按钮,请确保该按钮的CausesValidation = true。

你有它。

6
Page.MaintainScrollPositionOnPostBack = False 
Page.SetFocus(txtManagerName)