WPF用户控件中的键盘输入不会发送到WinForms容器

WPF用户控件中的键盘输入不会发送到WinForms容器,wpf,winforms,winforms-interop,Wpf,Winforms,Winforms Interop,我们有一个WinForms应用程序,正在逐步转换为WPF。此时,应用程序的主窗体是一个窗体(WinForm),其中包含内置于WPF中的垂直侧栏。侧栏位于ElementHost控件中 在主窗体中,KeyPreview设置为true,我们重写OnKeyDown()以处理应用程序范围的键盘快捷键。当侧边栏具有焦点时,键盘事件不会发送到OnKeyDown 什么是正确的方法? < P>是的,似乎KEYPREVIEW不是由EnthestOST考虑的,这里有一个解决方案: 从ElementHost派生并重写P

我们有一个WinForms应用程序,正在逐步转换为WPF。此时,应用程序的主窗体是一个窗体(WinForm),其中包含内置于WPF中的垂直侧栏。侧栏位于ElementHost控件中

在主窗体中,KeyPreview设置为true,我们重写OnKeyDown()以处理应用程序范围的键盘快捷键。当侧边栏具有焦点时,键盘事件不会发送到OnKeyDown


什么是正确的方法?

< P>是的,似乎KEYPREVIEW不是由EnthestOST考虑的,这里有一个解决方案:

从ElementHost派生并重写ProcessCmdKey,当base.ProcessCmdKey结果显示“未处理”时,将消息传递给父级,即使它不是您的主窗体,这样您的主窗体也将接收它,因为其他winforms控件将正常工作。这是一个样本

public class KeyPreviewEnabledElementHost : ElementHost
{
    public KeyPreviewEnabledElementHost()
    {
    }

    [DllImport("user32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); 

    protected override bool ProcessCmdKey(ref System.Windows.Forms.Message m, System.Windows.Forms.Keys keyData)
    {
        bool processed = base.ProcessCmdKey(ref m, keyData);

        if (!processed)
        {
            SendMessage(Parent.Handle, m.Msg, m.WParam, m.LParam);
        }

        return processed;
    }
}

我认为,如果可能的话,最好使用WPF窗口作为根,并托管Winforms内容。我知道它会解决这个问题,但它可能会带来新的问题。