WPF: OnKeyDown() not being called for space key in control derived from WPF TextBox

旧城冷巷雨未停 提交于 2019-11-28 00:43:52

The PreviewKeyDown event exists exactly for this sort of thing.

private void spacebarHandler_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Space)
        e.Handled = true;
}

Your KeyDown handler will never receive the KeyDown event for spacebar.

It seems the problem is that the space (and backspace etc.) key down event is being handled already within the TextBox, before it bubbles up to my derived control. I assume as part of the text composition process, as Wim posted.

To workaround this, I've added a handler that will receive the key down event even it has already been handled, and sets its Handled member to false, to allow it to carry on bubbling up normally. In the example below it just does this for space keys, but in my case I'll need to make it do this for any key events that I really don't want handled in my SelectedableTextBlock, as I don't know what key events parents might be interested in yet.

public class SelectableTextBlock : TextBox
{
    public SelectableTextBlock() : base()
    {
        this.AddHandler(SelectableTextBlock.KeyDownEvent, new RoutedEventHandler(HandleHandledKeyDown), true);
    }

    public void HandleHandledKeyDown(object sender, RoutedEventArgs e)
    {
        KeyEventArgs ke = e as KeyEventArgs;
        if (ke.Key == Key.Space)
        {
            ke.Handled = false;
        }
    }
    ...
}

I am of course still interested if anyone has a better solution...

Thanks, E.

I had this issue with spaces and events once in a textbox. Are the events NOT triggered only when you add or remove a space character?

This is what I got as an answer: (http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/446ec083-04c8-43f2-89dc-1e2521a31f6b)

Because some IMEs will treat whitespace keystroke as part of the text composition process, that's why it eats up by Avalon to report correct composited text through TextInput event.

I could be completely out of the scope but reading this thread emmideatly made me think of that issue I once had.

Kind regards, Wim

Derive a say, RestrictKeysTextBox from TextBox.

public class RestrictKeysTextBox : TextBox
{
    ....
}

Override the OnPreviewKeyDown event in the RestrictKeysTextBox.

Put logic in this override like this:

if (e.Key == Key.Space)
{
    e.Handled = true;
}

Bind the instance of the RestrictKeysTextBox to your DataGrid.

That should work without overriding the OnPreviewKeyDown in the DataGrid and eliminate the associated problems.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!