Internet Explorer 5.5Internet Explorer 7Internet Explorer 6.0IEWebFormsVisual Studio 2005.NET 2.0XMLAjaxC# 2.0IntermediateDevVisual StudioJavascriptWindows.NETASP.NETC#
在 ASP.NET 2.0 和 ASP.NET AJAX 中保持回传之间的焦点






4.87/5 (33投票s)
在 ASP.NET 2.0 和 ASP.NET AJAX 中保持回传之间的焦点,没有使用 SmartNavigation 的解决方法。
问题
假设您有两个 TextBox
。第一个有一个附加的 TextChanged
事件,并且 AutoPostBack
设置为 true
。 当您编辑 TextBox1
并移动到 TextBox2
时,控件 TextBox2
会失去焦点。
情况 1: ASP.NET 2.0 中没有智能导航的正常回传。
诀窍是保存最后获得焦点的控件的名称,然后在回传后恢复它。 存在一个隐藏字段 __LASTFOCUS
,我们将使用它。
首先,让我们遍历所有“相关”控件,并设置 onfocus
属性以在它们获得焦点时保存它们的名称。“相关”是指可能获得焦点的控件。 由于我们不想将此属性显式地设置为每个控件,我们只需定义“相关”控件的类型并递归枚举它们。
protected void Page_Load(object sender, EventArgs e)
{
//sets onfocus event to all apropriate controls on the page.
if (!IsPostBack)
HookOnFocus(this.Page as Control);
}
/// <summary>
/// This function goes recursively all child controls and sets
/// onfocus attribute if the control has one of defined types.
/// </summary>
/// <param name="CurrentControl">the control to hook.</param>
private void HookOnFocus(Control CurrentControl)
{
//checks if control is one of TextBox, DropDownList, ListBox or Button
if ((CurrentControl is TextBox) ||
(CurrentControl is DropDownList) ||
(CurrentControl is ListBox) ||
(CurrentControl is Button))
//adds a script which saves active control on receiving focus
//in the hidden field __LASTFOCUS.
(CurrentControl as WebControl).Attributes.Add(
"onfocus",
"try{document.getElementById('__LASTFOCUS').value=this.id}
catch(e) {}");
//checks if the control has children
if (CurrentControl.HasControls())
//if yes do them all recursively
foreach (Control CurrentChildControl in CurrentControl.Controls)
HookOnFocus(CurrentChildControl);
}
在函数 private void HookOnFocus(Control CurrentControl)
下的第一个 if
条件中添加额外的控件类型。
现在,我们需要在回传后设置焦点。 将以下 JavaScript 插入到您的页面中作为常量
/// <summary>
/// This script sets a focus to the control with a name to which
/// REQUEST_LASTFOCUS was replaced. Setting focus heppens after the page
/// (or update panel) was rendered. To delay setting focus the function
/// window.setTimeout() will be used.
/// </summary>
private const string SCRIPT_DOFOCUS =
@"window.setTimeout('DoFocus()', 1);
function DoFocus()
{
try {
document.getElementById('REQUEST_LASTFOCUS').focus();
} catch (ex) {}
}";
并将此语句添加到 Page_Load
中
protected void Page_Load(object sender, EventArgs e)
{
//sets onfocus event to all apropriate controls on the page.
if (!IsPostBack)
HookOnFocus(this.Page as Control);
//replaces REQUEST_LASTFOCUS in SCRIPT_DOFOCUS with
//the posted value from Request
//["__LASTFOCUS"]
//and registers the script to start after the page was rendered
Page.ClientScript.RegisterStartupScript(
typeof(MyPage),
"ScriptDoFocus",
SCRIPT_DOFOCUS.Replace("REQUEST_LASTFOCUS",
Request["__LASTFOCUS"]),
true);
}
情况 2:ASP.NET 2.0 AJAX 中 UpdatePanel 内部的“微型回传”
唯一的区别是必须在 UpdatePanel
内部的每次更新后设置焦点。 在这种情况下,使用 Page.ClientScript.RegisterStartupScript()
注册的脚本仅在每次全局回传后执行。 我们需要使用 ScriptManager.RegisterStartupScript()
替代。 Page_Load
看起来像这样
protected void Page_Load(object sender, EventArgs e)
{
//sets onfocus event to all apropriate controls on the page.
if (!IsPostBack)
HookOnFocus(this.Page as Control);
//replaces REQUEST_LASTFOCUS in SCRIPT_DOFOCUS with the posted value from
//Request ["__LASTFOCUS"]
//and registers the script to start after Update panel was rendered
ScriptManager.RegisterStartupScript(
this,
typeof(MyPage),
"ScriptDoFocus",
SCRIPT_DOFOCUS.Replace("REQUEST_LASTFOCUS", Request["__LASTFOCUS"]),
true);
}