9

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

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

我究竟做错了什么?

4

5 回答 5

6

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

于 2013-09-11T15:25:02.020 回答
4

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

于 2012-02-01T12:51:39.570 回答
3

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

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

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

于 2012-02-01T13:09:52.220 回答
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 也不需要实现起来很麻烦的消息泵。但我不知道是否可以处理这样的快捷键,因为我不需要它。

于 2016-01-28T14:24:45.150 回答
1

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

于 2012-01-31T17:16:17.133 回答