当焦点位于 WindowsFormsHost 并且上下文菜单打开时,上下文菜单不会响应向上/向下箭头键的按下。
下面的(几乎是自包含的)代码说明了这个问题:
<Window x:Class="FocusAndWinformsSimple.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
Title="MainWindow" Height="350" Width="525">
<DockPanel Name="DockPanel">
<DockPanel.ContextMenu>
<ContextMenu>
<MenuItem Header="aaa"/>
<MenuItem Header="bbb"/>
</ContextMenu>
</DockPanel.ContextMenu>
<StackPanel>
<TextBox/>
<WindowsFormsHost>
<wf:MaskedTextBox/>
</WindowsFormsHost>
</StackPanel>
</DockPanel>
</Window>
和后面的代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
InputBindings.Add(
new KeyBinding(
new RelayCommand(OpenContextMenu),
new KeyGesture(Key.T, ModifierKeys.Control)));
}
void OpenContextMenu()
{
DockPanel.ContextMenu.PlacementTarget = DockPanel;
DockPanel.ContextMenu.Placement = PlacementMode.Center;
DockPanel.ContextMenu.IsOpen = true;
}
}
这将显示两个文本框,一个 WPF 和一个 WinForms。如果您按 Ctrl-T,则会出现一个简单的上下文菜单。
现在运行程序
- 将光标放在 WPF 文本框中
- 按 Ctrl-T:出现上下文菜单
- 按向下箭头:选择上下文菜单中的第一项 ('aaa')。
然而
- 将光标放在 WinForms 文本框中
- 按 Ctrl-T:出现上下文菜单
- 按向下箭头:没有任何反应
在我们的应用程序中,键盘导航是必不可少的,所以这很烦人。
谁能帮我解释一下?最好想出一个解决方案,让第二种情况像第一种一样工作。
(我注意到,普通菜单 - 至少使用助记符打开 - 工作正常)。
更新
我想,我应该详细说明一下我正在研究的真实案例:我有一个 TabControl,其中每个 TabItem 的内容都是在其他地方开发的(但通常很复杂)。我的 Ctrl-T 上下文菜单将显示选项卡项标题列表,以便在选项卡之间快速导航。(它模仿 Visual Studio 中选项卡右侧的组合框)。
现在,当当前选项卡的内容是 WPF 控件并且焦点在控件内时,一切正常。如果您打开上下文菜单并选择相同的选项卡,焦点将返回到上下文菜单打开之前的位置。这是有效的,因为上下文菜单是一个焦点范围,所以逻辑焦点保持在控件内的位置。
但是,如果内容是 WindowsFormHost,并且焦点在其中,则上下文菜单不会像上面解释的那样工作。下面的第一个答案通过在打开上下文菜单之前将焦点移动到任何 WPF 控件来解决此问题。不幸的是,这也改变了逻辑焦点,使得在上下文菜单关闭后无法重置它。
我曾尝试在更改焦点和打开上下文菜单之前捕获并保存焦点,但没有成功。
我已经解决的解决方案是仅在必要时改变焦点。(检查Keyboard.FocusedElement == null
似乎工作)。这意味着我的解决方案仅在您将焦点放在 WinForms 组件中、打开上下文菜单并选择不更改选项卡的情况下是次优的。这很少见,所以它比我的第一个问题有了很大的改进。
但我仍然很好奇是否存在更好的解决方案。