We're trying to programmatically mimic the way the 'Up' and 'Down' arrow keys navigate around a TreeView
from code-behind. (Note: Not simply selecting items, but mimicking arrow-key navigation.)
Specifically, our use-case is one of our TreeView
's HierarchicalDataTemplates
has a TextBox
in it, which of course steals all keyboard activity when focused. But since this is a single-line TextBox
, we want to basically have it ignore the 'Up' and 'Down' keys and instead pass them to the underlying TreeView
to be processed there.
To do this, we subclassed the TextBox
and are intercepting the 'Up' and 'Down' keys in the OnPreviewKeyDown
override as follows...
protected override void OnPreviewKeyDown(System.Windows.Input.KeyEventArgs e)
{
switch(e.Key)
{
case Key.Up:
case Key.Down:
// Swallow the key
e.Handled = true;
// Get the navigation direction
var direction = (e.Key == Key.Up)
? FocusNavigationDirection.Up
: FocusNavigationDirection.Down;
// Perform the navigation
MoveFocus(new TraversalRequest(direction));
break;
default:
base.OnPreviewKeyDown(e);
break;
}
}
This technique works great when the TextBox
is in a ListBox
's DataTemplate
, but does not work if it's in a TreeView
's HierarchicalDataTemplate
.
Again, don't confuse this with simply selecting items. We already know how to programmatically do that by binding a TreeViewItem
's IsSelected
property to our ViewModel or manually walking the visual tree to get to the TreeViewItem
we want. I'm specifically asking about navigating around the TreeView
, duplicating what the 'Up' and 'Down' keys do.
For instance, if an earlier sibling has its children expanded and you press up, it goes to the last child of that sibling (or its child's children if it is expanded, etc.) If the earlier siblings children are collapsed, then it goes directly to that sibling. There's additional rules if they are visible or enabled, etc.
We have also tried explicitly setting the focus to the TreeViewItem
directly and performing MoveFocus
on that, but that didn't work either. Even tried calling that logic via a dispatcher to make sure the focus had actually changed. Again, nothing.
We also tried playing with KeyboardNavigation.DirectionalNavigation
, both on the TreeView
itself as well as against a TreeViewItem
but still, nothing.
Even if we have to do a SendKeys
-type of thing, that would be helpful.