C# WPF:在从 WPF TextBox 派生的控件中,没有为空格键调用 OnKeyDown()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1458748/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 17:45:50  来源:igfitidea点击:

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

c#wpftextboxonkeydown

提问by Ergwun

In a WPF application, I have a control that I have derived from TextBox like this:

在 WPF 应用程序中,我有一个从 TextBox 派生的控件,如下所示:

public class SelectableTextBlock : TextBox
{
    protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);
        e.Handled = false;
    }
}

The OnKeyDown method is not called when entering a space into the TextBox, nor when hitting Backspace, but does fire for other input including normal printable characters (e.g. 'a') and modifier keys (e.g. ).

OnKeyDown 方法在 TextBox 中输入空格时不会调用,也不会在按 Backspace 时调用,但会触发其他输入,包括普通可打印字符(例如 'a')和修饰键(例如 )。

I'm using this control with IsReadOnly set to true so I can display selectable, uneditable text. The control used within WPFToolkit's DataGrid, and I want KeyDown events to propagate up the data grid, even if the SelectableTextBlock has focus, which is why I am using a custom control to explicitly mark the event as unhandled.

我在 IsReadOnly 设置为 true 的情况下使用此控件,以便我可以显示可选择的、不可编辑的文本。WPFToolkit 的 DataGrid 中使用的控件,我希望 KeyDown 事件向上传播数据网格,即使 SelectableTextBlock 具有焦点,这就是我使用自定义控件将事件显式标记为未处理的原因。

The problem is that the event isn't even making it to my control for certain keys. I can't just use OnPreviewKeyDown in the DataGrid to get round this, since I do want other controls used in the data grid to swallow the space KeyDown event.

问题是该事件甚至没有让我控制某些键。我不能只在 DataGrid 中使用 OnPreviewKeyDown 来解决这个问题,因为我确实希望在数据网格中使用其他控件来吞下空间 KeyDown 事件。

Does anyone know how I can get the KeyDown event for the space key to propagate up?

有谁知道如何让空格键的 KeyDown 事件向上传播?

Thanks.

谢谢。

采纳答案by Ergwun

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.

似乎问题是空格(和退格键等)键按下事件已经在 TextBox 中处理,然后它冒泡到我的派生控件。正如 Wim 发布的那样,我认为这是文本编写过程的一部分。

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 reallydon't want handled in my SelectedableTextBlock, as I don't know what key events parents might be interested in yet.

为了解决这个问题,我添加了一个处理程序,即使它已经被处理,它也会接收键按下事件,并将其 Handled 成员设置为 false,以允许它继续正常冒泡。在下面的示例中,它仅对空格键执行此操作,但在我的情况下,我需要为我真的不想在我的 SelectedableTextBlock 中处理的任何关键事件执行此操作,因为我不知道哪些关键事件父母可能感兴趣呢。

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.

谢谢,E。

回答by hypo

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)

这是我得到的答案:(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.

因为某些 IME 会将空格键击视为文本组合过程的一部分,这就是 Avalon 需要通过 TextInput 事件报告正确的组合文本的原因。

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

亲切的问候,维姆

回答by Mac

Derive a say, RestrictKeysTextBox from TextBox.

从 TextBox 派生一个说,RestrictKeysTextBox。

public class RestrictKeysTextBox : TextBox
{
    ....
}

Override the OnPreviewKeyDown event in the RestrictKeysTextBox.

覆盖 RestrictKeysTextBox 中的 OnPreviewKeyDown 事件。

Put logic in this override like this:

将逻辑放在这个覆盖中,如下所示:

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

Bind the instance of the RestrictKeysTextBox to your DataGrid.

将 RestrictKeysTextBox 的实例绑定到您的 DataGrid。

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

这应该可以在不覆盖 DataGrid 中的 OnPreviewKeyDown 的情况下工作并消除相关问题。

回答by ivan

The PreviewKeyDown event exists exactly for this sort of thing.

PreviewKeyDown 事件正是为这种事情而存在的。

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.

您的 KeyDown 处理程序永远不会收到空格键的 KeyDown 事件。