在切换选项卡时,如何防止嵌套的 UserControl 中的 ToolBar 被聚焦?

How do I prevent a ToolBar in a nested UserControl from being focused when switching tabs?

我写了一个突出显示该问题的示例应用程序,这可能与 focus-scope 有关,因为每当涉及 ToolBar 并且在切换选项卡时卸载 UserControl 时。

主 window 包含一个带有文件->新建命令的菜单和一个显示 collection 个 "Box" 实例的 TabControl:

<DockPanel>
    <Menu DockPanel.Dock="Top">
        <MenuItem Header="_File">
            <MenuItem Command="New"/>
        </MenuItem>
    </Menu>

    <TabControl ItemsSource="{Binding Boxes}">
        <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}" Width="40"/>
            </DataTemplate>
        </TabControl.ItemTemplate>
        <TabControl.ContentTemplate>
            <DataTemplate>
                <local:BoxView/>
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>
</DockPanel>

每个 "Box" 实例都有一个 Name 属性 显示在选项卡 header 中,其余部分显示在 "BoxView" 用户控件。 "BoxView" 有一个工具栏,其第一个按钮在上述用例中成为 focus hog。 "BoxView" 还显示每个 "Box" 实例中的 collection of "Compartments":

<StackPanel>
    <ToolBarTray IsLocked="True">
        <ToolBar>
            <Button Content="Focus hog"/>
        </ToolBar>
    </ToolBarTray>

    <ItemsControl ItemsSource="{Binding Compartments}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <local:CompartmentView/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</StackPanel>

每个 "Compartment" 实例都有一个 TotalValue 属性 简单地显示在 "CompartmentView" 用户控件的文本框中:

<StackPanel>
    <TextBox Text="{Binding TotalValue}"/>
</StackPanel>

问题是...

如果我单击任何一个 CompartmentView 的文本框,然后单击主 window 的不同选项卡,BoxView 工具栏的第一个按钮将获得焦点(focus hog 一个), 禁用主要工作的命令 window.

打开“文件”菜单时可以观察到命令被禁用。但是在关闭菜单并重新打开后,命令又被启用了。

如何防止嵌套的UserControl中的ToolBar在切换标签时被聚焦?

或者我可能做错了...如何防止在切换标签页时设置焦点?

更新

以下 link 是 youtube 上的一个视频,我在其中解释了应用程序的问题。 https://youtu.be/0T5LK3CYxgw

解决方案更新

感谢 themightylc 的回答,问题显然是 键盘焦点 问题,当焦点视觉控件(任何选定的 "CompartmentView" 或 "BoxView" 控件) 在更改 TabControl 中的选定选项卡时被卸载。解决方案是在选项卡选择发生变化时,在主要 window 中关注 TabControl 本身:

private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    (sender as TabControl).Focus();
}

还要感谢 Christoph Nahr 对此 msdn 线程的解决方案的回复:https://social.msdn.microsoft.com/Forums/vstudio/en-US/f5de6ffc-fa03-4f08-87e9-77bbad752033/a-focusscope-nightmare-bug-commands-are-disabled?forum=wpf

<Button Content="Focus hog" Focusable="False" />

这解决了您遇到的问题。 Focusable 是一个 DependencyProperty 如果您仍想通过 Keyboard-Focus 访问工具栏,您可以绑定它或在 Tab-Switch 完成时从代码隐藏设置它。

您当然可以通过样式设置它,这样您就不必在工具栏的每个元素上都设置它。