【问题标题】:Maintain Control focus across post backs using PostBackOptions.TrackFocus使用 PostBackOptions.TrackFocus 在回发中保持控制焦点
【发布时间】:2011-07-01 14:34:08
【问题描述】:

在后背上保持专注显然是一项艰巨的任务。搜索谷歌,你会发现很多人都渴望同样的东西,但都以不同的方式联系起来,而且大多是习惯性的。我想避免自定义实现,特别是如果.NET 支持它的方式。只有经过一些非常深入的搜索,我才遇到 PostBackOptions.TrackFocus,在另一个堆栈溢出帖子中悄悄提到。根据 MSDN:

获取或设置一个值,该值指示回发事件是否应将页面返回到当前滚动位置并将焦点返回到当前控件。"

天哪,.NET 4 支持吗?惊人的。但是我们有大量的自定义控件,.NET 怎么知道如何将焦点设置在控件上?我不知道。查看 System.Web.UI.Control 的 MSDN 文档,有一个有趣的方法:

public virtual void Focus()

"使用 Focus 方法将网页的初始焦点设置为 控制。该页面将在带有控件的浏览器中打开 被选中。”

好的,显然可以覆盖。但是这样做的推荐方法是什么?它返回无效。没有例子。找不到任何人在其实现中覆盖此方法的示例。但是,在覆盖它并且除了抛出异常之外什么都不做之后,很明显这不是 ASP.NET 获得焦点的方式,该控件在回发之前具有焦点:它永远不会被调用。

在使用 Firebug 进行大量调试后,我发现启用 PostBackOptions.TrackFocus 有效!有时。很明显,控件的焦点只有在控件调用 __doPostBack JavaScript 方法时才会保持。启动 PostBack 的其他控件(当在控件内按 enter 时)调用 WebForm_OnSubmit(),它不会更新 ASP 隐藏字段 __LASTFOCUS。 __doPostBack 在设置隐藏字段后调用 WebForm_OnSubmit()。

这是我目前卡住的地方。无论如何,我似乎都需要调用 __doPostBack。关于使用 TrackFocus 的文档非常非常少。那么这里有人有什么建议吗?

【问题讨论】:

    标签: c# asp.net focus postback dopostback


    【解决方案1】:

    我一直在使用本文中的方法保持对回发的关注: (即:将焦点存储在所有控件的字段输入事件客户端的 __LASTFOCUS 隐藏字段中)

    http://www.codeproject.com/KB/aspnet/MainatinFocusASPNET.aspx

    如果您已经让 __LASTFOCUS 出现在页面上,那么这应该可以帮助您完成剩下的大部分工作......

    注意:最好能找到一种方法来防止多余的 javascript 膨胀 __VIEWSTATE。

    在我发现我的一些页面包含隐藏的 __LASTFOCUS 字段而我的一些页面没有之前,它对我来说工作得很好。 (这就是促使我四处搜索并找到您的问题的原因)现在我只是想弄清楚如何确保 __LASTFOCUS 始终显示在我想要跟踪关注的每个页面上......(看起来我会必须打开一个单独的问题)

    【讨论】:

    • 我的问题是我无法控制__LASTFOCUS。我没有把它放在那里:我不知道它是如何被 ASP 使用的,是什么让我有权仅仅因为我能够在客户端编写脚本而对其进行处理?如果 ASP 随机取走它会发生什么? (就像它对你所做的那样)不好。如果您打算这样做,为什么不直接在母版页中添加您自己的自定义 lastfocus 隐藏元素?
    • 还有一个问题:在回发后给页面添加控件。将最后一个焦点存储在隐藏元素中,然后回发。在页面中具有焦点的控件上方动态添加一个控件:现在唯一的 ClientId 已更改,您的控件将不会保持焦点,因为它的 ID 已更改。
    • @Sam.Rueby 我认为只要控件的 ID 在回发中不发生变化,这种方法应该仍然有效吗?特别是如果您创建一个单独的 __LASTFOCUS 隐藏字段。注意:所有页面加载中的 Page.SetFocus() 将确保 __LASTFOCUS 存在,在这里询问和回答:stackoverflow.com/questions/6684181/…
    【解决方案2】:

    这就是我刚刚所做的。假设您的代码中有一个处理程序来处理事件并具有如下签名:

    protected void myEventHandler(object sender, EventArgs e)
    

    您可以使用这行代码将焦点恢复到发送对象:

            ScriptManager.RegisterStartupScript((WebControl) sender, sender.GetType(), "RestoreFocusMethod", "document.getElementById(\"" + ((WebControl) sender).ClientID + "\").focus();", true);
    

    仅使用发送控件的 Focus() 方法将重新定位页面(如果您向下滚动一点),但这很有效。如果您的控件有特定的处理程序,则可以只使用控件本身,而不是将发送方强制转换为 WebControl,如下所示:

        protected void CityListDropDown_SelectedIndexChanged(object sender, EventArgs e)
        {
            ...
            ScriptManager.RegisterStartupScript(CityListDropDown, CityListDropDown.GetType(), "CityDropDownRefocus", "document.getElementById(\"" + CityListDropDown.ClientID + "\").focus();", true);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-22
      • 1970-01-01
      • 1970-01-01
      • 2015-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多