65.9K
CodeProject is changing. Read more.
Home

Set Error-Control Focus as per TabIndex

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (1 vote)

Jan 28, 2013

CPOL

2 min read

viewsIcon

13731

downloadIcon

59

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.