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

本文关键字:滚动 Ctrl-Arrow 默认 有可能 TreeView 是否 | 更新日期: 2023-09-27 18:15:39

我们有一个TreeView,我们想手动处理CTRL-Arrow键组合。但是,内置的行为是滚动列表而不实际更改所选项。

是否有任何方法可以禁用此功能,以便即使控制键按下,箭头也会改变所选项目?

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

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

TreeView中的键盘选择代码是丑陋的…我试图实现正确的多选择和键盘导航代码只是不是很可扩展。

我最终调用了一个非公共方法,作为一个体面的入口点:

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代码:)。