0

I don't know if this is a good way to work but i need to handle all unhandled keystrokes on my ViewModel so my idea was to use a Behavior on my ShellView that would relay all unhandled keystrokes to the ViewModel..

But the problem is how do i get all unhandled key presses?

Here is my first try to just catch them

Public Class ForwardKeyBehavior
    Inherits Behavior(Of DependencyObject)

    Protected Overrides Sub OnAttached()
        Keyboard.AddKeyDownHandler(Me.AssociatedObject, AddressOf OnKeyPressed)
        Keyboard.AddPreviewKeyDownHandler(Me.AssociatedObject, AddressOf OnPreviewKeyPressed)
        MyBase.OnAttached()
    End Sub

    Protected Overrides Sub OnDetaching()
        Keyboard.RemoveKeyDownHandler(Me.AssociatedObject, AddressOf OnKeyPressed)
        MyBase.OnDetaching()
    End Sub

    Private Sub OnPreviewKeyPressed(ByVal sender As Object, ByVal e As KeyEventArgs)

    End Sub

    Private Sub OnKeyPressed(ByVal sender As Object, ByVal e As KeyEventArgs)
        If (Not e.Handled) Then
            Trace.Write(e.Key.ToString())
        End If
    End Sub

End Class

But it seems that e.Handled always is false so what am i missing even if i press a key in a textbox?

chriga
  • 798
  • 2
  • 12
  • 29
Peter
  • 37,042
  • 39
  • 142
  • 198

2 Answers2

0

You set e.Handled = True to tell the program that the event has been handled and to stop executing any other functions that are registered to that event.

For example, if you hook up two methods to the KeyPressed event, and the first one sets e.Handled = True, then the 2nd event will never get executed.

I am guessing that all you really need to do is make sure your UnhandledKeyPressedEvent comes last in the event sequence, and that any other KeyPressed events set e.Handled = True to prevent the UnhandledKeyPressedEvent from executing.

Rachel
  • 130,264
  • 66
  • 304
  • 490
  • and how would i "make sure your UnhandledKeyPressedEvent comes last in the event sequence"? – Peter Dec 01 '10 at 07:43
  • and how would i go about doing that? i tried to hook up the event after "Keyboard.AddGotKeyboardFocusHandler" but that didn't help.. – Peter Dec 01 '10 at 15:09
  • On anything that should handle a KeyPress event, attach an event and set e.Handled = True. Then on the main page add a KeyPress event that goes to your ViewModel. The code in the ViewModel will only get executed if the KeyPressed event does not trigger an event that sets e.Handled = True. – Rachel Dec 01 '10 at 16:43
  • that might work but it would go against the spirit of mvvm? but how do the internal controls manage this? look at my comment one post up. there must be some way to know if the keypress was consumed by the textbox, the normal wpf controls seem to be able to do so.. – Peter Dec 02 '10 at 09:33
  • Some events have different routing strategies... WPF uses Bubble, Tunnel, and Direct. Google "WPF RoutingStrategy" for more info. And I normally don't mind code behind in mvvm providing the code-behind is UI related only. If you're really concerned about it you could use something like http://marlongrech.wordpress.com/2008/12/04/attachedcommandbehavior-aka-acb/ to attach VM commands to regular events such as KeyPressed event – Rachel Dec 02 '10 at 13:09
0

Check out MSDN

Pay attention to "The Concept of Handled" section, especially the handledEventsToo part.

treehouse
  • 2,521
  • 1
  • 21
  • 39
  • well yes this seems helpful but the problem is that even if i select a textbox and press D the d is added to the textbox but my event still fires... so what am i missing? – Peter Dec 01 '10 at 07:40
  • Add a KeyPressed event to the TextBox that says `e.Handled = true` – Rachel Dec 01 '10 at 13:10
  • @Petoj: It seems you misunderstand the concept of "being handled". Just because the textbox knows what to do with a key press doesn't mean the event will or should be marked as handled. Think about this example: you want a textbox NOT to show the letter "D" when you press "d". Now, if you press "d", nothing happens in the textbox. Can you say now the key press event is not being handled? No! You textbox is handleing the event (to ignore the letter "d"). If you want RoutedEvent infrastructure to stop routing an event. You need to explicitly tell it so by setting e.Handled to True. – treehouse Dec 01 '10 at 14:18
  • @Kai Wang: ok but is there any way to check if the textbox used the key press or not? lets say i place a multi line textbox(with 2 or more lines) inside a Listbox (with scrolls). now ill focus the textbox and press the Down key.. what would happen? a. Would the curser in the textbox go down one line. b. Would the listbox scroll down. c. Would i move the curser and scroll down? my guess is a, but how does the listbox know the textbox used that key stroke? – Peter Dec 01 '10 at 14:33
  • In answer to "how does the listbox know the textbox used that key stroke:" It doesn't. The text box eats the keypress, so the listbox never hears about it. Same thing will happen with the PageUp/PageDown keys. – stone Mar 01 '11 at 20:04