views:

2082

answers:

2

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

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. ).

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.

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.

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

Thanks.

A: 

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

hypo
Thanks for your reply, Wim.This seems like a related problem. I've found that the event are not triggered for space characters and backspace and delete key presses.Whereas in your case you were trying to stop the space key press being handled by the text box and did it by handling the preview, I'm trying to let the event bubble up to parent controls so this wouldn't work for me.I've got a workaround that handles handled key down events and sets them to handled. I'll post the code for general interest in a reply to my original question. Still think there must be a better way.Thanks, E.
Ergwun
That should have read: "I've got a workaround that handles handled key down events and sets them to *unhandled*."
Ergwun
+1  A: 

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.

Ergwun