2009-09-22 28 views
15

衍生在WPF应用控制空格键时,我有已经从文本框衍生这样的控制:WPF:的onkeydown()没有被调用用于从WPF文本框

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事件?

谢谢。

回答

12

看来问题是空间(和退格等)键按下事件被已经处理的文本框之内,它冒泡到我的派生控制之前。正如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.

2

我曾经在文本框中使用过空格和事件。只有当您添加或删除空格字符时才触发事件?

这是我作为一个答案:(http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/446ec083-04c8-43f2-89dc-1e2521a31f6b

因为有些输入法会将空格按键为文本创作过程的一部分,这就是为什么它吃了由阿瓦隆通过的TextInput报告正确的复合文本事件。

我可能完全超出了范围,但阅读这个线程emmideatly让我想起我曾经有过的那个问题。

亲切的问候,维姆

+0

感谢您的回复,Wim。 这看起来像一个相关的问题。我发现事件不会触发空格字符和退格键并删除按键。 而在你的情况下,你试图停止空格键被文本框处理,并通过处理预览,我试图让事件冒泡到父级控制,所以这不适用于我。 我有一个解决办法处理处理关键事件并将其设置为处理。我会在回复我的原始问题时发布一般感兴趣的代码。仍然认为必须有更好的方法。 谢谢,E. – Ergwun 2009-09-23 00:36:37

+0

这应该是这样写的:“我有一个解决办法来处理关键事件,并将它们设置为* unhandled *。 – Ergwun 2009-09-30 00:35:23

2

派生的发言权,RestrictKeysTextBox从文本框。

public class RestrictKeysTextBox : TextBox 
{ 
    .... 
} 

重写RestrictKeysTextBox中的OnPreviewKeyDown事件。在此覆盖这样

认沽逻辑:

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

绑定RestrictKeysTextBox到你的DataGrid的实例。

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

14

PreviewKeyDown事件正好存在于这类事情中。

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

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

+1

在.NET 4.5中不适用于我。 – Logan 2016-03-02 14:00:41

+2

它在.Net中工作4.6.1 – Dabblernl 2016-05-24 20:24:16