WinForms KeyDown 事件在首次使用时丢失键盘输入

发布于 2024-10-15 22:25:06 字数 1201 浏览 4 评论 0原文

我正在尝试制作一个 WinForms 程序,使 TextBox 通常隐藏(Visible = false),直到用户开始在键盘上打字,此时 TextBox 应该变得可见,并且键盘输入应该进入 TextBox。

这是程序,精简为基本部分:

using System.Windows.Forms;

namespace TestTextEditPopup
{
   public partial class Form1 : Form
   {
      public Form1()
      {
         InitializeComponent();

         this.KeyPreview = true;
         textBox1.Visible = false;
      }

      protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
      {
         if (keyData != Keys.Escape)
            return base.ProcessCmdKey(ref msg, keyData);

         textBox1.Visible = false;
         return true;  // Key has been processed
      }

      private void Form1_KeyDown(object sender, KeyEventArgs e)
      {
         textBox1.Visible = true;
         textBox1.Focus();
      }
   }
}

这是一系列屏幕截图:

And Here's a series of screen shot

首先我敲击键盘上的“a”。这确实会导致文本框变得可见并获得焦点,但“a”显然在某处丢失了。

然后我按了 Esc。这正确地使文本框再次不可见。

然后我按了“b”。这次(并且对于所有,或至少几乎所有后续时间)它起作用了 - TextBox 变得可见,获得焦点,并且键盘输入不会丢失 - 它显示在 TextBox 中。

关于为什么第一次不起作用有什么建议吗?或者完成我想做的事情的替代方法?

谢谢。

编辑:只需添加 KeyPress 作为附加标签。

I'm trying to make a WinForms program such that a TextBox is normally hidden (Visible = false) until the user starts typing on the keyboard, at which point the TextBox should become visible and the keyboard input should go into the TextBox.

Here's the program, reduced to the essential parts:

using System.Windows.Forms;

namespace TestTextEditPopup
{
   public partial class Form1 : Form
   {
      public Form1()
      {
         InitializeComponent();

         this.KeyPreview = true;
         textBox1.Visible = false;
      }

      protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
      {
         if (keyData != Keys.Escape)
            return base.ProcessCmdKey(ref msg, keyData);

         textBox1.Visible = false;
         return true;  // Key has been processed
      }

      private void Form1_KeyDown(object sender, KeyEventArgs e)
      {
         textBox1.Visible = true;
         textBox1.Focus();
      }
   }
}

And here's a series of screen shots:

And here's a series of screen shots

First I hit "a" on the keyboard. This does cause the TextBox to become visible and get focus, but the "a" is apparently lost somewhere.

Then I hit Esc. This correctly makes the TextBox invisible again.

Then I hit "b". This time (and for all, or at least almost all subsequent times) it works - the TextBox becomes visible, gets focus, and the keyboard input is not lost - it shows up in the TextBox.

Any suggestions as to why it doesn't work the first time? Or alternative methods of accomplishing what I'm trying to do?

Thanks.

Edit: Just adding KeyPress as an additional tag.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夕嗳→ 2024-10-22 22:25:07

请改用表单上的 KeyPress 事件;然后您可以访问字符数据,因此您可以将字符添加到 TextBox 控件中,然后将其聚焦:

private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (this.ActiveControl != textBox1)
    {
        textBox1.Visible = true;
        textBox1.Focus();
        textBox1.Text += e.KeyChar;
        textBox1.Select(textBox1.Text.Length, 0);
        e.Handled = true;
    }                
}

Use the KeyPress event on the form instead; then you get access to character data, so you can add the character to the TextBox control, and then focus it:

private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (this.ActiveControl != textBox1)
    {
        textBox1.Visible = true;
        textBox1.Focus();
        textBox1.Text += e.KeyChar;
        textBox1.Select(textBox1.Text.Length, 0);
        e.Handled = true;
    }                
}
时光暖心i 2024-10-22 22:25:07

来自KeyPreview 文档

当该属性设置为 true 时,
表单将接收所有 KeyDown(等)事件。之后
表单的事件处理程序已完成
处理击键,
然后将按键分配给
集中控制。

当表单启动时,文本框控件被禁用,因此没有焦点。

由于当按下第一个键时,文本框控件没有焦点,因此按键会丢失,因为表单无法处理它:在后续按键中,控件会接收输入,因为它仍然具有焦点 - 我猜它是唯一的窗体上的控件,因为如果有另一个控件,当文本框被禁用时焦点会转移到它,并且后​​续的按键将像第一个按键一样消失。

另一种方法是从表单边界之外的文本框开始,然后将其移入和移出,而不是使其可见/不可见。

From the docs for KeyPreview

When this property is set to true, the
form will receive all KeyDown (etc) events. After the
form's event handlers have completed
processing the keystroke, the
keystroke is then assigned to the
control with focus.

When the form starts, the textbox control is disabled and hence does not have focus.

As when the first key is pressed the textbox control does not have the focus, the keypress is lost as the form cannot process it: on subsequent keypresses, the control receives the input as it still has focus - I'm guessing it is the only control on the form, because if there was another control the focus would shift to it when the textbox became disabled, and subsequent keypresses would disappear like the initial one.

Another way of doing this would be to start off with the textbox outside the form boundaries and shift it in and out rather than make it visible / invisible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文