Alt键和选项卡在从WPF应用程序打开的Windows窗体中不起作用

时间:2012-01-31 17:11:42

标签: c# wpf winforms alt-key

我有很多旧的Windows窗体应用程序,最终将移植到WPF(它是一个大型应用程序,因此无法在一个sprint中完成),我已经通过在WPF中创建主菜单开始了这个过程。 Windows窗体应用程序是从此菜单打开的单独窗口。

Windows窗体应用程序正在打开并正常工作除了我使用快捷方式和 Tab 键时出现的问题。 Tab键没有将焦点移动到下一个控件,而用于触发& Search按钮的 Alt 键不再有效。

我做错了什么?

5 个答案:

答案 0 :(得分:4)

我发现的部分解决方案是从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

答案 1 :(得分:3)

我终于设法通过在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 close事件。

答案 2 :(得分:3)

这是设计的。快捷键在消息循环级别处理,在 Windows消息被调度到具有焦点的窗口之前检测到。这就是这些键无论焦点如何都可以工作的原因。

问题是,你没有Winforms消息循环来消息。 Application.Run()由WPF在您的程序中实现,而不是Winforms。因此,Winforms中处理键盘消息以实现快捷键击的任何代码都不会运行。

对此没有好的解决方案,它基本上是“无法怀孕”的问题。 Winforms中的此代码被严重锁定,因为它允许CAS旁路。唯一的解决方法是使用ShowDialog()方法显示包含Winforms控件的Form派生类。该方法泵出一个模态消息循环,Winforms一个,足以恢复快捷键击处理代码。通过首先转换主窗口,最后转换对话框来重构您的方法。

答案 3 :(得分:2)

我发现处理焦点在 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也不需要消息泵,这可能是一个麻烦实现。但我不知道是否可以处理这样的快捷键,因为我不需要它。

答案 4 :(得分:1)

检查是否已分配IsTabStop="True"TabIndex。对于Alt + Key快捷方式,请尝试使用下划线(_)字符而不是&符号(&amp;)。