【问题标题】:KeyboardNavigation.ControlTabNavigation Application Wide?KeyboardNavigation.ControlTabNavigation 应用范围?
【发布时间】:2012-03-27 14:06:08
【问题描述】:

我有一个一直在尝试处理的问题 - 如下:

KeyboardNavigation.ControlTabNavigation="None"

尽管我尽了最大努力,但似乎在我的应用程序中的任何地方都不起作用...我不完全确定为什么,但不管我做什么,CTRL+TAB 功能总是有效,在我的情况下,这种行为是有害的我希望我的选项卡控件如何操作。理想情况下,我不想在我的应用程序的每个容器中放置上述标记(无论如何我都无法工作),我想在整个应用程序中禁用 ControlTabNavigation。有没有办法做到这一点,而不必逐个容器地去容器,是否有任何明显的“陷阱”通常会使上述内容无法正常工作?

谢谢! 阿杰

【问题讨论】:

  • 在某种程度上,我正在经历同样的事情。我可以让 KeyboardNavigation.ControlTabNavigation="None" 在 TabControl 上工作,但是,仅在我用鼠标选择(即左键单击)一个 Tab 之前。那时,我可以再次跨标签按 Ctrl-Tab,这与我寻求(和期望)发生的情况相反。你有没有在其他地方得到任何关于这个问题的反馈,或者你自己取得了任何进展?谢谢。
  • 一厢情愿...如果您遇到解决方案,但请发布。

标签: wpf xaml keyboard-shortcuts tabcontrol


【解决方案1】:

我发现 KeyboardNavigation 无法正常工作,因为它与 Ctrl-Tab 和 TabControl 相关。我整理了一个简单的原型,KeyboardNavigation.ControlTabNavigation="None" 似乎对使用 Ctrl-Tab 切换选项卡没有预期的影响,一旦我左键单击一个选项卡并且键盘焦点位于 TabControl 内。

但是,将 InputBindings 与 Command 结合使用可能会覆盖不需要的 Ctrl-Tab 默认行为。从那里,我发现KeyboardNavigation.TabNavigation="Cycle" 以及 TabNavigation 的其他其他选项似乎表现合理。使用以下资源链接中描述的 FocusManager 和其他技术应该可以让人们获得所需的键盘导航,尽管使用了一些违反直觉的技术。

必须为具有不需要的默认行为的每个控件设置 InputBindings,尽管例如,更复杂的解决方案可能会遍历可视化树来为特定类型的所有控件设置 InputBindings。我发现让命令根本不做任何事情来充分中和键序列。在我的示例中,我显示了一个用于测试的对话框。

注意,下面的命令绑定要求您以 WPF 4.0 为目标;有关如何针对 WPF 3.5 或更早版本的资源,请参阅帖子末尾的资源

在 XAML 中:

<TabControl 
    x:Name="tabControl1"
    IsSynchronizedWithCurrentItem="True"
    SelectedItem="{Binding SelectedTabItem}"
    ItemsSource="{Binding TabItemViewModels}"
    KeyboardNavigation.ControlTabNavigation="None"
    KeyboardNavigation.TabNavigation="Continue">

            <TabControl.InputBindings>
                <KeyBinding Modifiers="Control"
                    Key="Tab"
                    Command="{Binding ShowDialogCommand}" />
            </TabControl.InputBindings>
</TabControl>

注意,在上面的 XAML 中,KeyboardNavigation.ControlTabNavigation="None" 是无效的,可以消除。

在支持 DataContext 中,通常是 ViewModel:

声明你的绑定属性:

public RelayCommand ShowDialogCommand
{
     get;
     private set;
}

初始化属性;例如,可以在 ViewModel 的构造函数中(注意,RelayCommand 来自 MVVM-Light 库。):

ShowDialogCommand = new RelayCommand(() =>
            {
                MessageBox.Show("Show dialog box command executed", "Show Dialog Box Command", MessageBoxButton.OK, MessageBoxImage.Information); 
            });

资源:

Helpful StackOverflow post on KeyBindings

More detail on KeyBinding to a Command; describes special CommandReference technique needed if targeting WPF framewrok 3.5 or earlier

Microsoft's Focus Overview

【讨论】:

    【解决方案2】:

    我已经有一段时间没有关注这个问题了,但自从比尔问到它之后,我又重新燃起了兴趣。正如比尔建议的那样,我没有通过控制来控制,而是使用了一个空命令,但将它应用于 TabControl 模板......正如比尔指出的那样,这有点违反直觉的解决方案,但它有效(我也考虑了 Ctrl+Shift +Tab 是 Ctrl+Tab 的反方向):

    我的班级:

    public static readonly RoutedCommand CancelTabChangeCommand = new RoutedCommand() { };
    

    XAML:

    <Style TargetType="{x:Type TabControl}">    
      <Setter Property="Template">
         <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabControl}">
               <Grid ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
                        <Grid.InputBindings>
                            <KeyBinding Command="{x:Static local:myClass.CancelTabChangeCommand}" Key="Tab" Modifiers="Control" />
                            <KeyBinding Command="{x:Static star:Startup.CancelTabChangeCommand}" Key="Tab" Modifiers="Shift+Control"/>
                        </Grid.InputBindings>
    

    我放弃了我的课程和 XAML 的其余部分,因为它与示例无关,但如果有人需要,我很乐意提供更多。在相关说明中,我还发现为 TabItem 创建一个控件模板并将 IsTabStop 属性设置为 false 也可以防止我的用户以这种方式切换和更改选项卡......以防万一有人遇到这个问题我是。

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-16
      • 1970-01-01
      • 2013-02-07
      • 1970-01-01
      相关资源
      最近更新 更多