Alt键和制表符不要';无法在从WPF应用程序打开的Windows窗体中工作
本文关键字:应用程序 WPF 工作 窗体 Windows 制表符 Alt | 更新日期: 2023-09-27 18:21:57
我有很多旧的Windows窗体应用程序,它们最终将被移植到WPF(这是一个大型应用程序,因此无法在一次sprint中完成),我已经通过在WPF中创建主菜单开始了这个过程。Windows窗体应用程序是从该菜单打开的独立窗口。
Windows窗体应用程序正在打开和工作,没有任何问题,除了快捷方式和选项卡键的问题。tab键没有将焦点移动到下一个控件,并且Alt键触发&"搜索"按钮不再工作。
我做错了什么?
我发现的一个部分解决方案是从WPF构造函数调用它:System.Windows.Forms.Integration.WindowsFormsHost.EnableWindowsFormsInterop();(您需要引用dll WindowsFormsIntegration.dll)
我之所以说部分是因为并非所有的按键都能按预期工作。对简单的表格来说似乎还可以。
请参阅:
http://msdn.microsoft.com/en-us/library/system.windows.forms.integration.windowsformshost.enablewindowsformsinterop(v=vs.100).aspx
我最终通过在WPF表单内的WindowsFormsHost控件中托管winform来解决问题。
public partial class MyWindow : Window
{
public MyWindow()
{
InitializeComponent();
Form winform = new Form();
// to embed a winform using windowsFormsHost, you need to explicitly
// tell the form it is not the top level control or you will get
// a runtime error.
winform.TopLevel = false;
// hide border because it will already have the WPF window border
winform.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.windowsFormsHost.Child = winform;
}
}
请注意,如果您有关闭表单的按钮,您可能还需要挂接winform关闭事件。
这是经过设计的。快捷键在消息循环级别进行处理,在将Windows消息发送到具有焦点的窗口之前检测到。这就是为什么无论焦点如何,这些键都可以工作的原因。
问题是,您没有Winforms消息循环来泵送消息。Application.Run()是由程序中的WPF实现的,而不是Winforms。因此,Winforms中任何处理键盘消息以实现快捷键的代码都不会运行。
对此没有好的解决方案,从根本上说,这是"不能怀孕"的问题。Winforms中的此代码被严重锁定,因为它将允许绕过CAS。唯一的解决方法是显示包含Winforms控件的Form派生类及其ShowDialog()方法。该方法产生了一个模式消息循环,即Winforms循环,足以恢复快捷键处理代码。通过首先转换主窗口,最后转换对话框来重新构建方法。
我发现的另一个处理Tab键焦点的解决方案是像这样覆盖OnKeyDown:
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.Tab)
{
HandleFocus(this, ActiveControl);
}
else
{
base.OnKeyDown(e);
}
}
internal static void HandleFocus(Control parent, Control current)
{
Keyboard keyboard = new Keyboard();
// Move to the first control that can receive focus, taking into account
// the possibility that the user pressed <Shift>+<Tab>, in which case we
// need to start at the end and work backwards.
System.Windows.Forms.Control ctl = parent.GetNextControl(current, !keyboard.ShiftKeyDown);
while (null != ctl)
{
if (ctl.Enabled && ctl.CanSelect)
{
ctl.Focus();
break;
}
else
{
ctl = parent.GetNextControl(ctl, !keyboard.ShiftKeyDown);
}
}
}
此解决方案的优点是,它既不需要WindowsFormsHost,也不需要消息泵,这可能会给实现带来麻烦。但我不知道是否可以处理这样的快捷键,因为我不需要它
检查是否分配了IsTabStop="True"
和TabIndex
。对于Alt + Key
快捷方式,请尝试使用下划线(_)字符而不是与号(&)。