简体   繁体   中英

How I set focus on previous textbox control by using Shift + Tab key?

I show you my code by which I send my cursor focus on next control but I want to set focus on previous control by pressing shift + tab key.

protected override bool ProcessTabKey(bool forward)
    {
        Control ctl = this.ActiveControl;
        if (ctl != null && ctl is TextBox)
        {
            TextEdit tb = (TextEdit)ctl.Parent;
            if (SelectTextBoxes.Contains(tb) && tb.Text.Length == 0)
            {
                return true;
            }
        }
        return base.ProcessTabKey(forward); // process TAB key as normal
    }

Try to do it the next way. Turn on KeyPreview so the form can register all key presses. Input all controls that have TabStop turned on to a single list and order that list by tab index. Override OnKeyDown to check if shift key is pressed or not and inside ProcessTabKey method go forward if only tab was pressed or go backwards if shift + tab was pressed.

private List<Control> _tabControls = new List<Control>();

public MyForm()
{
    InitializeComponent();

    this.KeyPreview = true;

    TabControlsToList(this.Controls);
    _tabControls = _tabControls.OrderBy(x => x.TabIndex).ToList();
}

private void TabControlsToList(Control.ControlCollection controls)
{
    foreach (Control control in controls)
    {
        if (control.TabStop == true)
            _tabControls.Add(control);

        if (control.HasChildren)
            TabControlsToList(control.Controls);
    }
}

protected override void OnKeyDown(KeyEventArgs args)
{
    if ((args.Modifiers == Keys.Shift) && (args.KeyCode == Keys.Tab))
        interceptTabKey = !interceptTabKey;

    base.OnKeyDown(args);
}

private bool interceptTabKey = true;
protected override bool ProcessTabKey(bool forward)
{
    // We can intercept/process the [Keys.Tab] via this method.
    if (interceptTabKey)
    {
        if (forward)            // [Keys.Shift] was not used
        {
            this.SelectNextControl(this.ActiveControl, true, true, true, true);
        }
        else                    // [Keys.Shift] was used
        {
            int currentIndex = _tabControls.IndexOf(this.ActiveControl);
            var control = _tabControls[currentIndex == 0 ? _tabControls.Count - 1 : currentIndex - 1];
            control.Select();
        }

        // [return true;]  -- To indicate that a control is selected.
        return true;
    }

    // Do this normally when not intercepted
    return base.ProcessTabKey(forward);
}

Below code works fine in my project. And thanks to Smola because I modify his code to achieve my goal.

private List<TextEdit> SelectTextBoxes = new List<TextEdit>();
    public Form1()
    {
        InitializeComponent();
        this.KeyPreview = true;
        SelectTextBoxes = new List<TextEdit>() 
        { 
            textEdit1,textEdit3, textEdit4, textEdit2
        };
        SelectTextBoxes = SelectTextBoxes.OrderBy(x => x.TabIndex).ToList();
    }

    protected override void OnKeyDown(KeyEventArgs args)
    {
        if ((args.Modifiers == Keys.Shift) && (args.KeyCode == Keys.Tab))
        {
            interceptTabKey = !interceptTabKey;
        }

        base.OnKeyDown(args);
    }

    private bool interceptTabKey = true;
    protected override bool ProcessTabKey(bool forward)
    {
        TextEdit tb = (TextEdit)this.ActiveControl.Parent;
        // We can intercept/process the [Keys.Tab] via this method.
        if (interceptTabKey)
        {
            if (forward)            // [Keys.Shift] was not used
            {
                if (SelectTextBoxes.Contains(tb) && tb.Text.Length > 0)
                this.SelectNextControl(this.ActiveControl, true, true, true, true);
            }
            else                   // [Keys.Shift] was used
            {
                int currentIndex = SelectTextBoxes.IndexOf(tb);
                var control = SelectTextBoxes[currentIndex == 0 ? SelectTextBoxes.Count - 1 : currentIndex - 1];
                control.Select();
            }

            // [return true;]  -- To indicate that a control is selected.
            return true;
        }
        // Do this normally when not intercepted
        return base.ProcessTabKey(forward);
    }

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