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

时间:2009-09-22 08:17:51

标签: c# wpf textbox onkeydown

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

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

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

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

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

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

感谢。

4 个答案:

答案 0 :(得分:15)

PreviewKeyDown事件完全存在于此类事物中。

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

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

答案 1 :(得分:14)

似乎问题是空间(和退格等)键向下事件已在TextBox中处理,然后才会冒泡到我的派生控件。我假设作为文本撰写过程的一部分,正如Wim发布的那样。

为了解决这个问题,我添加了一个处理程序,即使它已被处理,也会收到按键事件,并将其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;
        }
    }
    ...
}

如果有人有更好的解决方案,我当然仍然感兴趣...

谢谢, 即

答案 2 :(得分:2)

我在文本框中遇到过一次空格和事件的问题。是否仅在添加或删除空格字符时才触发事件?

这就是我得到的答案:( http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/446ec083-04c8-43f2-89dc-1e2521a31f6b

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

我可能完全超出了范围但是阅读这个帖子让我想起了曾经有过的那个问题。

亲切的问候, 维姆

答案 3 :(得分:2)

从TextBox中获取RestrictKeysTextBox。

public class RestrictKeysTextBox : TextBox
{
    ....
}

覆盖RestrictKeysTextBox中的OnPreviewKeyDown事件。

将逻辑置于此覆盖中,如下所示:

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

将RestrictKeysTextBox的实例绑定到DataGrid。

这应该不会覆盖DataGrid中的OnPreviewKeyDown并消除相关问题。