views:

3387

answers:

3

I have a canvas inside a scrollview. I attached a keydown event handler to the scrollview. For most keys, the handler gets called.

However, for the arrow keys, the handler does not get called. Instead, the scrollview gets scrolled in the appropriate direction.

I also attached a keyup handler to the scrollview and the keyup does get called for the arrow keys.

Is there any way to get the arrow key down event here?

+1  A: 

I found this silly hack to make it work. Setting the scrollview to not be a tabstop keeps it from eating the key events.. but then I had another textbox on the page that all of a sudden ALWAYS had focus because the scrollview didn't anymore. So I fixed that by letting an invisible textbox get focus.

scrollView.IsTabStop = false;

invisibleTextBox.Foreground = new SolidColorBrush(Colors.Transparent);
invisibleTextBox.Background = new SolidColorBrush(Colors.Transparent);
Canvas.SetZIndex(invisibleTextBox, -1000);
invisibleTextBox.KeyDown += new KeyEventHandler(HandleKeyDown);
invisibleTextBox.KeyUp += new KeyEventHandler(HandleKeyUp);

Edit: I also had to move the text box off the canvas because despite being invisible, its outline still showed up.

2nd Edit: I used a textbox because that was the first thing I found that could capture KeyDown events. However, a UserControl can. So it would probably be better practice to use a UserControl instead of an invisible text box. You can call Focus() on the UserControl if needed.

Mike Blandford
A: 

This is a possible answer - I haven't had a chance to test this. I've had similar trouble in the past though, when a control is consuming the events before you can get at them. There's a few things you may be able to try:

  1. Use the PreviewKeyDown event, I think that's what it's called. It may let you get at the event before it's consumed by the control.
  2. Try mblandfo's suggestion, although if you do this you probably ant to wrap the whole thing up in a user control to hide what you're doing from the rest of your code.
  3. Add a key handler to the Canvas object, you may be able to catch the event there, and "bubble" it up through your own event.

Except for 1) all of these count as hacks, really, but good luck, I hope one of them works for you!

George Sealy
A: 

"Use the PreviewKeyDown event, I think that's what it's called. It may let you get at the event before it's consumed by the control."

This works. Just set the event arguments "Handled = true" and the ScrollViewer (or ListBox) wont grab onto the event after you've already handled it. I didn't need to use the IsTabStop property for the ListBox though; that and it didn't seem to do anything anyways.

Adam
that works in WPF, but silverlight does not have a preview key down
Mike Blandford