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.