如何使用 Shift + Tab 键将焦点设置在先前的文本框控件上?

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

我向您展示了我的代码,通过该代码我将光标焦点发送到下一个控件,但我想通过按 shift + tab 键将焦点设置到上一个控件。

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
    }

尝试下一种方法。打开 KeyPreview 以便表单可以注册所有按键。将所有已打开 TabStop 的控件输入到一个列表中,并按选项卡索引对该列表进行排序。覆盖 OnKeyDown 以检查 shift 键 是否被按下,如果仅 tab 被按下,则在 ProcessTabKey 方法中继续或者如果按下 shift + tab 则向后移动。

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);
}

以下代码在我的项目中运行良好。还要感谢 Smola,因为我修改了他的代码以实现我的目标。

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);
    }