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

时间:2018-07-28 22:51:36

标签: c# wpf focus toolbar tabcontrol

我编写了一个示例应用程序,重点介绍了这个问题,这可能与focus-scope有关,因为只要涉及到工具栏,并且在切换选项卡时都卸载了UserControl,

主窗口包含一个带有File-> New命令的菜单和一个显示“ 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 属性,其余部分显示在“ BoxView” UserControl中。 “ BoxView”具有一个工具栏,在上述用例中,其第一个按钮成为 focus hog 。 “ BoxView”还显示每个“ Box”实例内的“舱”的集合:

<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>

每个“隔离专区”实例都有一个 TotalValue 属性,该属性仅显示在“ CompartmentView” UserControl的文本框中:

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

问题是...

如果我单击任一CompartmentView的TextBox,然后单击主窗口的其他选项卡,则BoxView的ToolBar的第一个按钮将被聚焦( focus hog ),禁用在主窗口中运行的命令。

可以看到打开“文件”菜单时命令被禁用。但是在关闭菜单并重新打开后,命令会再次启用。

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

或者我可能会遇到这个错误...在切换标签页时如何防止设置焦点?

更新

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

解决方案更新

多亏了他们的解决方案,当在更改菜单项中的选定选项卡时卸载了聚焦的视觉控件(任何选定的“ CompartmentView”或“ BoxView”控件)时,该问题显然是键盘焦点 TabControl。解决方案是,每当选项卡选择发生更改时,都将重点放在主窗口中的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

1 个答案:

答案 0 :(得分:1)

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

这可以解决您遇到的问题。 Focusable是一个DependencyProperty,如果您仍然想通过Keyboard-Focus来访问ToolBar,则可以在Tab-Switch完成后绑定它或从后面的代码中设置它。

您当然可以通过样式进行设置,因此不必在工具栏的每个元素上进行设置。