4

我在表单上有一个文本框,我试图检测用户输入的键。文本框是多行的,带有自动换行。我不希望用户按下回车键(因为我希望在一行上输入所有文本,包装)所以我使用了以下代码:

private void txtPlain_KeyPress(object sender, KeyPressEventArgs e) {
    if (e.KeyChar == (char)13) {
        MessageBox.Show("Enter keys are not allowed");
        e.KeyChar = (char)0;
    }
}

这在我的测试中运行良好,但是当我测试 CTRL+ENTER 时它不起作用,因为我不确定如何检测控制键。从我的谷歌搜索中,我发现我需要使用 KeyUp/Down 事件,所以我现在有以下代码:

private void txtPlain_KeyUp(object sender, KeyEventArgs e) {
    //if (e.KeyData == (Keys.Control | Keys.Enter)) {

    if (e.KeyCode == Keys.Enter || (e.KeyCode == Keys.Enter && e.Control)) {            
        MessageBox.Show("Enter keys are not allowed:");
        //e.KeyValue = Keys.None;
    }
}

由于某种原因,第一条注释掉的行不起作用,所以如果有人能解释为什么这会有用。

KeyUp/Down 事件的问题是我不知道如何从文本中删除输入键 - 与 KeyPress 事件不同,我可以将 KeyChar 设置为零。该事件同时捕获 Enter 和 Ctrl+Enter 键,但光标仍会转到 TextBox 中的下一行。

感谢您对此的任何帮助。

4

3 回答 3

5

嗯,没有理由通过处理or事件来禁止Enter密钥。您可以简单地将文本框控件的属性设置为 False。这将防止多行文本框响应按键。KeyDownKeyUpAcceptsReturnEnter

当然,这并不能解决Ctrl+的问题Enter。事实上,这是在AcceptsReturn属性设置为 False 时创建新行的预期方式。为了解决这个问题,您需要处理其中一个键盘事件并阻止控件接收此输入。

KeyDown是一个很好的起点。您要做的是过滤掉任何包含该Keys.Enter标志的键盘事件。无论它们可能与哪个其他修饰键组合,这都会捕获它们。然后,一旦你找到了一个 Enter 按键,你想将该e.Handled属性设置为 True 以防止它被传递给控件。

但不幸的是,我们还没有完成。文本框控件尝试在内部处理某些键,并且您将无法在键事件处理程序方法中覆盖它。您还需要告诉控件不要将该特定键解释为输入键。有两种主要方法可以做到这一点。第一种(也是推荐的方式)是从基TextBox类继承来创建自己的自定义控件,然后重写受保护的IsInputKey方法。第二种(稍微简单一点)的方法就是处理PreviewKeyDown事件,并将IsInputKey属性设置为 False。

示例代码:

private void txtPlain_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
    // Check if the KeyCode value has the Keys.Enter flag set
    if ((e.KeyCode & Keys.Enter) == Keys.Enter)
    {
        // Set the IsInputKey property to False
        e.IsInputKey = false;
    }
}

private void txtPlain_KeyDown(object sender, KeyEventArgs e)
{
    // Check if the KeyCode value has the Keys.Enter flag set
    if ((e.KeyCode & Keys.Enter) == Keys.Enter)
    {            
        // Show the user a message
        MessageBox.Show("Enter keys are not allowed in this textbox.");

        // Prevent the key event from being passed on to the control
        e.Handled = true;
    }
}

而且,虽然我认为这仅用于测试目的,但您肯定希望将MessageBox调用从那里用于生产代码。找到另一种方法来提醒用户他们的输入不被允许,例如短促的哔声和放置在文本框旁边的ErrorProvider组件。显示一个消息框是非常不和谐的,而且不是很人性化。有关其他提示和技巧,请参阅我的答案

于 2011-05-11T11:28:45.067 回答
1
private void txtPlain_KeyUp(object sender, KeyEventArgs e) {
    //if (e.KeyData == (Keys.Control | Keys.Enter)) {

    if (e.KeyCode == Keys.Enter || (e.KeyCode == Keys.Enter && e.Control)) {            
        MessageBox.Show("Enter keys are not allowed:");
        //e.KeyValue = Keys.None;
        // mark event as handled
        e.Handled = true;
    }
} 

来自 msdn链接

编辑:

我认为您需要按键按下事件而不是按键按下

EDIT2
这里是一些经过测试的代码,它可以按您的意愿工作:

        bool invalid=false;
        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            if ((e.KeyCode & Keys.Enter) == Keys.Enter)
            {
                invalid = true;
            }
        }

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (invalid)
            {
                e.Handled = true;
            }
            invalid = false;
        }
于 2011-05-11T11:26:06.080 回答
0

由于某种原因,第一条注释掉的行不起作用,所以如果有人能解释为什么这会有用。

您想检测 Ctrl + Enter。if (e.KeyData == (Keys.Control | Keys.Enter)) {..

Keys.Control 和 Key.Enter 只是一些值,请参考。现在做逻辑或不一定会导致已按下的键。完全不合逻辑的条款。

好的,现在来解决您想要检测 Enter 笔画和 Ctrl + Enter 笔画被视为相同的实际问题。此外,您还想撤消引入的换行符。尝试

具有以下条件的 PreviewKeyDown 或 Preview key up 事件处理程序

if(e.KeyCode==Keys.Enter)

让我知道这个是否奏效

于 2011-05-11T11:55:30.297 回答