19

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

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

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

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

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

有谁知道我怎样才能让空格键向上传播的 KeyDown 事件?

谢谢。

4

4 回答 4

24

PreviewKeyDown 事件正是针对这类事情而存在的。

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

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

于 2013-07-13T09:05:38.160 回答
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;
        }
    }
    ...
}

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

谢谢,E。

于 2009-09-23T00:45:43.883 回答
3

从 TextBox 派生出一个说法,RestrictKeysTextBox。

public class RestrictKeysTextBox : TextBox
{
    ....
}

覆盖 RestrictKeysTextBox 中的 OnPreviewKeyDown 事件。

将逻辑放入此覆盖中,如下所示:

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

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

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

于 2011-06-14T20:36:31.160 回答
2

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

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

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

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

亲切的问候,维姆

于 2009-09-22T13:51:08.007 回答