是否可以禁用 TreeView 的默认 Ctrl-Arrow 滚动行为?

Is it possible to disable the default Ctrl-Arrow scroll behaviors of a TreeView?

我们有一个 TreeView,我们希望在其上手动处理 CTRL-Arrow 组合键。但是,内置行为是在不实际更改所选项目的情况下滚动列表。

有什么方法可以禁用此功能,以便即使按下控制键,箭头也会更改所选项目?

注意:是的,我知道 PreviewKeyDown 函数,但是当我获取事件并处理它时,我不确定如何以编程方式使树中的选择按用户期望的那样工作。 (即尊重展开或折叠的节点,从一个分支跳到另一个分支等)

TreeView 中的键盘选择代码非常丑陋...我试图实现适当的多选,但键盘导航代码的可扩展性不是很好。

我最终调用了一个非public方法作为一个不错的入口点:

private delegate DependencyObject PredictFocusedElement(DependencyObject sourceElement, FocusNavigationDirection direction, bool treeViewNavigation, bool considerDescendants);

// get the default KeyboardNavigation instance

KeyboardNavigation keyboardNavigation = (KeyboardNavigation)typeof(FrameworkElement).GetProperty("KeyboardNavigation", BindingFlags.NonPublic | BindingFlags.Static).GetMethod.Invoke(null, null);

// create a delegate for the PredictFocusedElement method

_predictFocusedElement = (PredictFocusedElement)typeof(KeyboardNavigation).GetMethod("PredictFocusedElement", BindingFlags.NonPublic | BindingFlags.Instance, Type.DefaultBinder,
                                                                                        new Type[] { typeof(DependencyObject), typeof(FocusNavigationDirection), typeof(bool), typeof(bool) },
                                                                                        null).CreateDelegate(typeof(PredictFocusedElement), keyboardNavigation);

现在,一旦您拥有该委托,您就可以控制焦点:

tvi = (TreeViewItemEx)_predictFocusedElement(tvi, FocusNavigationDirection.Down, true, true);

tvi.Focus();

如果您想查看难看的代码,可以在 ILSpy 或其他任何地方查看 PredictFocusedElement 代码:)。