开发者

WPF: How to detect Key repetition, in Key* events?

NOTE: e.IsRepeat is confirmed to work. The problem exists because I use Remote Desktop from Ubuntu to Windows.

I found a workaround for this Remote Desktop problem:

  1. Disable key repetition in Ubuntu.
  2. In host Windows: Enable FilterKeys with "Turn on Repeat Keys and Slow Keys"
  3. Using regedit go to HKEY_CURRENT_USER\Control Panel\Accessibility\Keyboard Response
    1. Set AutoRepeatDelay, AutoRepeatRate, and Last Valid Delay, Last Valid Repeat to small enough.
    2. Disable FilterKeys and re-enable to refresh the registry changes.

How does one detect key repetition in KeyUp/KeyDown (or PreviewKeyDown/PreviewKeyUp) events?

I have following test case:

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

It gives me to Output screen following if I press letter D down and release it after a while:

// 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.

Apparently the e.IsRepeat is always false, so that is useless. I also noticed that sometimes the first event is also toggFalse, dowTrue, so that cannot be used as a pattern.

I also note that clever way of using timing can be used to detect repetition, but there must be a native way to do this.


Why not use the native possibilities? I added a PreviewKeyDown event on the window and two textboxes. Pressed and held a key in the second textbox and this is the output:

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

This is the code I used:

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

Update: removed all my code (there was some garbage from other tests) and pasted in your code as-is. It gives me the following output in the console, so I gather we should have a look at other causes...

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


Set a variable when the keydown event fires tracking which key is pressed, do your thing(tm) then ignore further events for that key. When keyup fires clear the variable. You may need a list to track multiple keys.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜