简体   繁体   中英

How to maintain tab order after postback

The requirement is for some calculation to happen on entering a value in the textbox and since calculation is same ontextchanged is linked to the same event. When I tab out it neatly goes to next control and does a postback to Calculate.

Now after the postback and the server side is called and executed, the tab order is messed up and on tab it does not bring focus to the correct control. It always points to the URL in the browser window.

Please let me know how do i retrieve the control which should be next in focus after the postback using the tabIndex.

  <asp:TextBox ID="txtDiscount" runat="server" CssClass="NormalTextBox" TabIndex="45"
                                    MaxLength="3" OnTextChanged="btnCalculatePrice_Click" AutoPostBack="True"></asp:TextBox>


  protected void btnCalculatePrice_Click(object sender, EventArgs e)
    {....

}

I tried the below code but didnt know how to fetch the exact control

   if(sender!=null)
        {
            WebControl reqCtrl = (WebControl)sender;
            int taborder = reqCtrl.TabIndex;
            int nexttabOrder = taborder + 1;

        }

Use below code in order to set focus to next control after post back.

protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
WebControl wcICausedPostBack = (WebControl)GetControlThatCausedPostBack(sender as Page);
int indx = wcICausedPostBack.TabIndex;
var ctrl = from control in wcICausedPostBack.Parent.Controls.OfType<WebControl>()
where control.TabIndex > indx
select control;
ctrl.DefaultIfEmpty(wcICausedPostBack).First().Focus();
}
}
protected Control GetControlThatCausedPostBack(Page page)
{
Control control = null;
string ctrlname = page.Request.Params.Get("__EVENTTARGET");
if (ctrlname != null && ctrlname != string.Empty)
{
control = page.FindControl(ctrlname);
}
else
{
foreach (string ctl in page.Request.Form)
{
Control c = page.FindControl(ctl);
if (c is System.Web.UI.WebControls.Button || c is System.Web.UI.WebControls.ImageButton)
{
control = c;
break;
}
}
}
return control;
}

Here is a similar (app code) solution that works for controls that may not necessarily share the same parent. It assumes the tab indexes are exactly 1 number apart.

protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack)
    {
        SetFocusAfterPostBack();
    }
}

public static void SetFocusAfterPostBack()
{
    var page = HttpContext.Current.Handler as Page;
    if (page == null)
    {
        return;
    }
    var postBackCtl = page.FindControl(HttpContext.Current.Request.Form["__EVENTTARGET"]) as WebControl;
    if (postBackCtl == null || postBackCtl.TabIndex == 0)
    {
        return;
    }
    var ctl = GetCtlByTabIndex(page, postBackCtl.TabIndex + 1);
    if (ctl != null)
    {
        ctl.Focus();
    }
}
private static WebControl GetCtlByTabIndex(Control ParentCtl, int TabIndex)
{
    foreach (Control ctl in ParentCtl.Controls)
    {
        var webCtl = ctl as WebControl;
        if (webCtl != null)
        {
            if (webCtl.TabIndex == TabIndex)
            {
                return webCtl;
            }
        }
        var retCtl = GetCtlByTabIndex(ctl, TabIndex);
        if (retCtl != null)
        {
            return retCtl;
        }
    }
    return null;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM