在切换选项卡时,如何防止嵌套的 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 完成时从代码隐藏设置它。
您当然可以通过样式设置它,这样您就不必在工具栏的每个元素上都设置它。
我写了一个突出显示该问题的示例应用程序,这可能与 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 完成时从代码隐藏设置它。
您当然可以通过样式设置它,这样您就不必在工具栏的每个元素上都设置它。