如何以编程方式导航(而不是选择,而是导航)WPF TreeView? [英] How can I programmatically navigate (not select, but navigate) a WPF TreeView?
问题描述
我们正在尝试以编程方式模仿向上"和向下"箭头键从后面的代码在TreeView
周围导航的方式. (注意:不仅要选择项目,还要模仿箭头键导航.)
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.)
具体地说,我们的用例是我们的TreeView
的HierarchicalDataTemplates
之一,其中包含TextBox
,当聚焦时,它当然会窃取所有键盘活动.但是,由于这是单行TextBox
,因此我们基本上希望它忽略'Up'和'Down'键,而是将它们传递给底层的TreeView
进行处理.
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.
为此,我们对TextBox
进行了子类化,并在OnPreviewKeyDown
替代中拦截了"Up"和"Down"键,如下所示...
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;
}
}
当TextBox
位于ListBox
的DataTemplate
中时,此技术很好用,但如果位于TreeView
的HierarchicalDataTemplate
中,则无效.
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
.
同样,不要将其与选择项目混淆.我们已经知道如何通过编程方式将TreeViewItem
的IsSelected
属性绑定到我们的ViewModel上,或者手动遍历可视树以获取所需的TreeViewItem
.我是专门问关于
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.
我们还尝试了将焦点直接直接设置为TreeViewItem
并对其执行MoveFocus
,但是那也不起作用.甚至尝试通过调度程序调用该逻辑,以确保焦点实际上已更改.再说一次,什么都没有.
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.
我们还尝试了在TreeView
本身上以及TreeViewItem
上同时使用KeyboardNavigation.DirectionalNavigation
的情况,但是仍然没有.
We also tried playing with KeyboardNavigation.DirectionalNavigation
, both on the TreeView
itself as well as against a TreeViewItem
but still, nothing.
即使我们必须做SendKeys
类型的事情,这也会有所帮助.
Even if we have to do a SendKeys
-type of thing, that would be helpful.
推荐答案
WPF UI自动化框架可能有一种方法.但是,如果没有成功,则该项目将执行以下操作:
The WPF UI Automation framework probably has a way to do it. But if that doesn't pan out, this project coded something to do it:
http://wpfsendkeys.codeplex.com/
这篇关于如何以编程方式导航(而不是选择,而是导航)WPF TreeView?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!