Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Set Error-Control Focus as per TabIndex

0.00/5 (No votes)
28 Jan 2013 2  
This article is created for setting the tab focus on the controls, where the error-provider has error text.

Introduction

This code can help set focus to error-control as per the Tab-Index set for controls.  

Background 

There is a recent need in Windows Forms, whenever a control validation process completes, the error tagged controls need to focus in ascending order. This article is created for setting the set tab focus on controls, where the error-provider has set error text. Here are some of the advantages:

  1. No need to find the error-marked control after validation.
  2. Even if the control is in nested containers, it gets focus if error text is found.
  3. Controls designed in Tab-Pages also taken care of even the tab not selected.
  4. Just set the Tab-Index at the form in sequence, and call the Common.SetTabFocus() function.

Using the code  

This can be used as a sample application and code snippet for setting focus to error control. It has a Windows form with only one button event, which validates and sets focus using Common class instance and functions defined into it. 

For using the Common class features, refer the code:   

Classes.Common common = new TabFocus.Classes.Common(this.errorProvider);
////Line below is just a example of Control Validation, this can vary
/// as per requirement or design, Pass the controls to be validated
common.Mandatory(txtFirstName, txtLastName, cmbGender, cmbReligion, txtNationality, txtLine1, txtCity);
if (!common.SetTabFocus(this, true))
{
    ////Do the needful process after validation success
    MessageBox.Show("Controls validated successfully.", 
      "Tab-Focus",  MessageBoxButtons.OK, MessageBoxIcon.Information);
}
common = null;

Function SetTabFocus(Control parentControl, bool focusInvalidControl) in Common class sets the tab focus after evaluating the controls from the parent form. The first parameter is a form to be validated for tab focus, and the second parameter decides the to focus control or not.

public bool SetTabFocus(Control parentControl, bool focusInvalidControl)
{
    string lTab = string.Empty;
    bool focusStatus = false;
    ////Check if it is a first parent call
    if ((this._controlName == null) & this._controlName != parentControl.Name)
    {
        this._minTabIndex = "0.0";
        this._controlName = parentControl.Name;
    }

    try
    {
        foreach (Control control in parentControl.Controls)
        {
            if (control.Controls.Count > 0)
            {
                this.SetTabFocus(control, false);
            }
            else if (control.Controls.Count == 0)
            {
                string tabIndex = string.Empty;
                if (Convert.ToDouble(this._minTabIndex) == 0.0)
                {
                    this._minTabIndex = this._keyTabIndex;
                }

                ////Get the formatted tab-index
                tabIndex = this.GetTabIdex(control, true);
                ////Replace the occurences to prepare comparison
                tabIndex = tabIndex.Replace(".", string.Empty);
                ////check if any validation/error is occured in control
                if (this._errorProvider.GetError(control) != string.Empty)
                {
                    if (Convert.ToDouble(this._minTabIndex) > Convert.ToDouble(this._keyTabIndex + 
                      "." + tabIndex) | Convert.ToDouble(this._minTabIndex) == Convert.ToDouble(this._keyTabIndex))
                    {
                        ////If error occured on control then set the latest minimal tab-index to main location
                        this._minTabIndex = this._keyTabIndex + "." + tabIndex;
                        ////set the control to focus
                        this._invalidDataControl = control;
                    }
                }

                tabIndex = null;
            }
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }
    finally
    {
        ////Check if it is a first parent call
        if (this._controlName == parentControl.Name)
        {
            this._controlName = null;
            ////Focus to be set as per flag and if the error control is found
            if (focusInvalidControl && (this._invalidDataControl != null))
            {
                this._tabPages = null;
                this._tabPages = new ArrayList();
                ////Find the tab-pages involved  in to be selected
                this.GetTabPages(this._invalidDataControl);
                if (this._tabPages != null && this._tabPages.Count > 0)
                {
                    foreach (TabPage tabPageItem in this._tabPages)
                    {
                        ////Select the tab-page of error control
                        ((TabControl)tabPageItem.Parent).SelectedTab = tabPageItem;
                        break;
                    }
                }
                ////Set the error control found
                this._invalidDataControl.Focus();
                focusStatus = true;
            }
        }
    }

    return focusStatus;
}

Function GetTabIdex(Control control, bool isFirstCall) in the Common class gets the tab-index for the given control. The first control is for which the tab-index to be retrieved, and the second to decide and initialise the variable tab-value. 

private string GetTabIdex(Control control, bool isFirstCall)
{
    if (isFirstCall == true)
    {
        this._tabIndex = string.Empty;
    }

    try
    {
        if (!(control is Form))
        {
            if (this._tabIndex == string.Empty)
            {
                this._tabIndex = control.TabIndex.ToString();
            }
            else
            {
                this._tabIndex = this._tabIndex.PadLeft(3, '0');
                this._tabIndex = control.TabIndex + "." + this._tabIndex;
            }
            this.GetTabIdex(control.Parent, false);
        }

        return this._tabIndex;
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

To set the right control to focus within the tab-pages, find the nested tab-controls and tab-pages:   

private void GetTabPages(Control control)
{
    ////If form is control then loop has achieved the top nested control, so exit method
    if (control.Parent is Form)
    {
        return;
    }
    else if (control.Parent is TabPage)
    {
        this._tabPages.Add(control.Parent);
    }
    ////Find the nested parent controls for current control's parent
    this.GetTabPages(control.Parent);
}

Points of Interest

Using this the automated errored control focus, a manual and redundant code in each form can be minimised at large context.

History 

Looking forward to queries for improvements.    

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here