按Enter键移动到下一个控件

20

我在WinForm上有几个文本框。我希望在按下回车键时,焦点能够转移到下一个控件。每当文本框获得控制权时,它也会选择文本,以便任何编辑都会替换当前文本。

最佳方法是什么?

9个回答

31

Tab键作为回车键:创建一个继承自文本框的用户控件,重写KeyPress方法。如果用户按下回车键,您可以调用SendKeys.Send("{TAB}")System.Windows.Forms.Control.SelectNextControl()。请注意,您还可以使用KeyPress事件实现相同的功能。

选中整个文本:同样,通过覆盖或事件,针对GotFocus事件并调用TextBox.Select方法。


2
当提供了一种完成任务的方法时,发送按键不是最好的解决方案。SelectNextControl可以执行与发送Tab键相同的功能,而无需发送按键的混乱。 - Fr33dan

30

使用SelectNextControl的几个C#代码示例。

第一个示例是在按下ENTER键时移动到下一控件。

    private void Control_KeyUp( object sender, KeyEventArgs e )
    {
        if( (e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return) )
        {
            this.SelectNextControl( (Control)sender, true, true, true, true );
        }
    }

第二种方法使用向上向下箭头在控件之间进行移动。

    private void Control_KeyUp( object sender, KeyEventArgs e )
    {
        if( e.KeyCode == Keys.Up )
        {
            this.SelectNextControl( (Control)sender, false, true, true, true );
        }
        else if( e.KeyCode == Keys.Down )
        {
            this.SelectNextControl( (Control)sender, true, true, true, true );
        }
    }

请参阅MSDN SelectNextControl 方法


1
我最喜欢的答案。这假定开发人员已经正确设置了控件的 TabStop 和 TabIndex 属性,他们应该始终这样做。 - Valid
5
如果您想将此应用于当前表单的所有控件,您可以将表单属性KeyPreview设置为True,注册表单的KeyUp事件,并在上面的代码中将“(Control)sender”替换为“ActiveControl”。 - JJGAP

11
在KeyPress事件中,如果用户按下Enter键,则调用
SendKeys.Send("{TAB}")

最好的实现在获得焦点时自动选择文本的方法是在项目中创建一个 TextBox 的子类,并使用以下覆盖方法:

Protected Overrides Sub OnGotFocus(ByVal e As System.EventArgs)
    SelectionStart = 0
    SelectionLength = Text.Length
    MyBase.OnGotFocus(e)
End Sub

然后在所有的表单中使用这个定制的文本框来代替WinForms标准文本框。


2
这可能会有所帮助:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
    //
    // Detect the KeyEventArg's key enumerated constant.
    //
    if (e.KeyCode == Keys.Enter)
    {
        MessageBox.Show("You pressed enter! Good job!");
    }
}

2

你可以在文本框上放置一个 KeyPress 处理程序,以查看使用了哪个键。

要处理文本选择,请在 GotFocus 事件上放置一个处理程序。

您还需要考虑如何处理多行文本框(如果需要的话)。


1
private void txt_invoice_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Enter)
            txt_date.Focus();
    }

    private void txt_date_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Enter)
            txt_patientname.Focus();
    }

}


0

如果您想经常使用此功能,也可以编写自己的控件。假设您在网格中有多个文本框,代码将类似于:

public class AdvanceOnEnterTextBox : UserControl
{

    TextBox _TextBox;
    public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(String), typeof(AdvanceOnEnterTextBox), null);
    public static readonly DependencyProperty InputScopeProperty = DependencyProperty.Register("InputScope", typeof(InputScope), typeof(AdvanceOnEnterTextBox), null);


    public AdvanceOnEnterTextBox()
    {
        _TextBox = new TextBox();
        _TextBox.KeyDown += customKeyDown;
        Content = _TextBox;

    }


    /// <summary>
    /// Text for the TextBox
    /// </summary>
    public String Text
    {
        get { return _TextBox.Text; }
        set { _TextBox.Text = value; }
    }


    /// <summary>
    /// Inputscope for the Custom Textbox
    /// </summary>
    public InputScope InputScope
    {
        get { return _TextBox.InputScope; }
        set { _TextBox.InputScope = value; }
    }


    void customKeyDown(object sender, KeyEventArgs e)
    {
        if (!e.Key.Equals(Key.Enter)) return;

        var element = ((TextBox)sender).Parent as AdvanceOnEnterTextBox;
        if (element != null)
        {
            int currentElementPosition = ((Grid)element.Parent).Children.IndexOf(element);
            try
            {
                // Jump to the next AdvanceOnEnterTextBox (assuming, that Labels are inbetween).
                ((AdvanceOnEnterTextBox)((Grid)element.Parent).Children.ElementAt(currentElementPosition + 2)).Focus();
            }
            catch (Exception)
            {
                // Close Keypad if this was the last AdvanceOnEnterTextBox
                ((AdvanceOnEnterTextBox)((Grid)element.Parent).Children.ElementAt(currentElementPosition)).IsEnabled = false;
                ((AdvanceOnEnterTextBox)((Grid)element.Parent).Children.ElementAt(currentElementPosition)).IsEnabled = true;
            }
        }
    }
}

当然,你可以这样做,但是在表单上拥有一个单一的方法比重新编写所有要使用的控件要容易得多,这将导致有一个庞大的代码库,并且以后调试它们也会更加困难。 - AaA

0
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        if (keyData == (Keys.Enter))
        {
            SendKeys.Send("{TAB}");
        }

        return base.ProcessCmdKey(ref msg, keyData);
    }

前往设计表单,然后查看->选项卡(如图片所示)Order,然后您就可以对所有控件进行排序[就是这样]

输入图像描述

从Behzad获取代码(https://dev59.com/yHRC5IYBdhLWcg3wOeSB) - AbdusSalam

-1
尝试使用:
SendKeys.Send("{TAB}")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接