9

注意e.IsRepeat已确认可以工作。存在问题是因为我使用从 Ubuntu 到 Windows 的远程桌面。

我找到了解决此远程桌面问题的方法:

  1. 在 Ubuntu 中禁用键重复。
  2. 在主机 Windows 中:使用“打开重复键和慢速键”启用 FilterKeys
  3. 使用 regedit 转到HKEY_CURRENT_USER\Control Panel\Accessibility\Keyboard Response
    1. AutoRepeatDelay,AutoRepeatRate,设置为足够小。 Last Valid DelayLast Valid Repeat
    2. 禁用 FilterKeys 并重新启用以刷新注册表更改。

如何检测KeyUp/ KeyDown(或PreviewKeyDown/ PreviewKeyUp)事件中的键重复?

我有以下测试用例:

    public Window1() {
        InitializeComponent();

        this.KeyDown += new KeyEventHandler(Window1_KeyDown);
        this.KeyUp += new KeyEventHandler(Window1_KeyUp);
    }

    void Window1_KeyUp(object sender, KeyEventArgs e) {
        if (e.Key == Key.D) {
            Console.WriteLine("DOWN: key: {0}, rep{1}, togg{2}, dow{3}, up{4}", e.Key, e.IsRepeat, e.IsToggled, e.IsDown, e.IsUp);
        }
    }

    void Window1_KeyDown(object sender, KeyEventArgs e) {
        if (e.Key == Key.D) {
            Console.WriteLine("UP: key: {0}, rep{1}, togg{2}, dow{3}, up{4}", e.Key, e.IsRepeat, e.IsToggled, e.IsDown, e.IsUp);
        }
    }

如果我按下字母 D 并在一段时间后释放它,它会给我以下输出屏幕:

// Note: Here I press D-key down.
UP: key: D, repFalse, toggTrue, dowTrue, upFalse
DOWN: key: D, repFalse, toggTrue, dowFalse, upTrue
UP: key: D, repFalse, toggFalse, dowTrue, upFalse
DOWN: key: D, repFalse, toggFalse, dowFalse, upTrue
UP: key: D, repFalse, toggTrue, dowTrue, upFalse
DOWN: key: D, repFalse, toggTrue, dowFalse, upTrue
UP: key: D, repFalse, toggFalse, dowTrue, upFalse
DOWN: key: D, repFalse, toggFalse, dowFalse, upTrue
UP: key: D, repFalse, toggTrue, dowTrue, upFalse
DOWN: key: D, repFalse, toggTrue, dowFalse, upTrue
UP: key: D, repFalse, toggFalse, dowTrue, upFalse
DOWN: key: D, repFalse, toggFalse, dowFalse, upTrue
UP: key: D, repFalse, toggTrue, dowTrue, upFalse
DOWN: key: D, repFalse, toggTrue, dowFalse, upTrue
UP: key: D, repFalse, toggFalse, dowTrue, upFalse
DOWN: key: D, repFalse, toggFalse, dowFalse, upTrue
UP: key: D, repFalse, toggTrue, dowTrue, upFalse
DOWN: key: D, repFalse, toggTrue, dowFalse, upTrue
UP: key: D, repFalse, toggFalse, dowTrue, upFalse
DOWN: key: D, repFalse, toggFalse, dowFalse, upTrue
UP: key: D, repFalse, toggTrue, dowTrue, upFalse
DOWN: key: D, repFalse, toggTrue, dowFalse, upTrue
UP: key: D, repFalse, toggFalse, dowTrue, upFalse
DOWN: key: D, repFalse, toggFalse, dowFalse, upTrue
// Note: Here I release D-key.

显然,e.IsRepeat总是假的,所以那是没用的。我还注意到,有时第一个事件也是toggFalse、dowTrue,所以不能用作模式。

我还注意到,可以使用巧妙的计时方式来检测重复,但必须有一种本地方式来做到这一点。

4

2 回答 2

9

为什么不使用本机可能性?我在窗口和两个文本框上添加了一个 PreviewKeyDown 事件。在第二个文本框中按住一个键,这是输出:

Repeat: False, key: D
Repeat: True, key: D
Repeat: True, key: D
Repeat: True, key: D
Repeat: True, key: D
Repeat: True, key: D
Repeat: True, key: D
Repeat: True, key: D

这是我使用的代码:

private void Grid_PreviewKeyDown(object sender, KeyEventArgs e)
{
    textBox1.Text += String.Format(
        "Repeat: {0}, key: {1}\n", 
        e.IsRepeat, 
        e.Key);
}

更新:删除了我所有的代码(其他测试中有一些垃圾)并按原样粘贴到您的代码中。它在控制台中给了我以下输出,所以我认为我们应该看看其他原因......

UP: key: D, repFalse, toggTrue, dowTrue, upFalse
UP: key: D, repTrue, toggTrue, dowTrue, upFalse
UP: key: D, repTrue, toggTrue, dowTrue, upFalse
UP: key: D, repTrue, toggTrue, dowTrue, upFalse
UP: key: D, repTrue, toggTrue, dowTrue, upFalse
UP: key: D, repTrue, toggTrue, dowTrue, upFalse
于 2009-12-04T16:30:17.570 回答
0

当 keydown 事件触发跟踪按下哪个键时设置一个变量,做你的事情(tm)然后忽略该键的进一步事件。当 keyup 触发时清除变量。您可能需要一个列表来跟踪多个键。

于 2009-12-04T16:25:35.490 回答