首先,我在表中有3个TextBox,一个DropDownList,一个CheckBox和2个LinkButtons。 TextBoxes和DropDownList必须执行AutoPostBack,因为在服务器端进行了一些由OnTextChanged调用的计算。
我的问题是,在任何Control(需要PostBack)的内容发生变化后,您尝试将焦点移动到页面上的任何其他Control(无论是Tab键还是使用鼠标点击任何其他Control)焦点不会移动到您单击的下一个Control或Control。
我尝试使用找到当前Control的方法并基于TabIndex,添加1将焦点移动到下一个控件。这里的问题是它不允许在除了具有下一个TabIndex的控件之外的任何其他控件上设置焦点。这里更好地解释一下这种情况的一个例子。
示例:我有TextBox1,TextBox2和TextBox3。我更改了TextBox2中的内容,然后想要向后移动到TextBox1。当我单击TextBox1时,焦点设置为TextBox3,因为代码使用TabIndex的顺序。 **这里的一个关键因素是TextBox1在服务器端代码触发之前获得焦点,但随后失去焦点并将其设置在TextBox3上**
对我来说,似乎可以实现的唯一方法是在客户端添加一个函数,在发生PostBack之前找到具有焦点的Control,然后在服务器端代码完成后重置该控件上的焦点。似乎我在服务器端做的任何事都不会起作用,因为当发生这种情况时焦点已经丢失。
我搜索过但搜索过但未能找到解决此问题的任何方法,我发现的所有内容都涉及将焦点设置到NEXT控件而不是您想要关注的控件。任何帮助将不胜感激。提前谢谢。
以下是我用于根据TabIndex移动到下一个Control的代码,但这在我的情况下不起作用。
protected void Page_Load(object sender, EventArgs e)
{
WebControl ctrl = GetPostBackControl() as WebControl;
if (ctrl != null && !SetNextFocus(Controls, ctrl.TabIndex + 1)) { ctrl.Focus(); }
}
public Control GetPostBackControl()
{
Control control = null;
string ctrlname = Request.Params.Get("__EVENTTARGET");
if (ctrlname != null && ctrlname != string.Empty)
{
control = FindControl(ctrlname);
control.Focus();
}
else
{
foreach (string ctl in Request.Form)
{
Control c = FindControl(ctl);
if (c is Button)
{
control = c;
break;
}
}
}
return control;
}
private bool SetNextFocus(ControlCollection controls, int tabIndex)
{
foreach (Control control in controls)
{
if (control.HasControls())
{
bool found = SetNextFocus(control.Controls, tabIndex);
if (found) { return true; }
}
WebControl webControl = control as WebControl;
if (webControl == null) { continue; }
if (webControl.TabIndex != tabIndex) { continue; }
webControl.Focus();
return true;
}
return false;
}
答案 0 :(得分:4)
尝试做这样的事情以在回发后保持焦点:
/// <summary>
/// Overrides the OnLoad event moves the cursor to the appropriate control.
/// </summary>
/// <param name="e"></param>
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
int currentTabIndex = 1;
WebControl postBackCtrl = (WebControl)GetControlThatCausedPostBack(Page);
foreach (WebControl ctrl in Panel1.Controls.OfType<WebControl>())
{
ctrl.TabIndex = (short)currentTabIndex;
if (postBackCtrl != null)
{
if (ctrl.TabIndex == postBackCtrl.TabIndex + 1)
ctrl.Focus();
}
currentTabIndex++;
}
}
/// <summary>
/// Retrieves the control that caused the postback.
/// </summary>
/// <param name="page"></param>
/// <returns></returns>
private Control GetControlThatCausedPostBack(Page page)
{
//initialize a control and set it to null
Control ctrl = null;
//get the event target name and find the control
string ctrlName = Page.Request.Params.Get("__EVENTTARGET");
if (!String.IsNullOrEmpty(ctrlName))
ctrl = page.FindControl(ctrlName);
//return the control to the calling method
return ctrl;
}
答案 1 :(得分:0)
感谢您的帮助,它确实让我更近了一点。唯一阻止它正常工作的是我的页面有一些变量从其他页面转移。页面加载时,覆盖会导致页面中断,因为它无法找到这些控件。我能够通过在.aspx页面上添加HiddenField并将以下代码添加到onload()函数来解决问题:
if (document.getElementById("HiddenField1").value != "") {
var contr = document.getElementById(document.getElementById"HiddenField1").value);
contr.focus();
document.getElementById("HiddenField1").value = "";
}
以及添加在每个TextBox上调用的新函数:
function tabFocus(e) {
document.getElementById("HiddenField1").value = e.id;
}
我最终不必对后面的代码进行任何更改。再一次,谢谢你的帮助!