简体   繁体   English

KeyDown、KeyUp 和 KeyPressed 不会在托管 WPF 控件的 WinForms 应用程序上触发

[英]KeyDown, KeyUp and KeyPressed won't fire on a WinForms app hosting a WPF control

I've made a test WinForms APP in C# targeting .NET 4.5.我已经在 C# 中针对 .NET 4.5 做了一个测试 WinForms APP。 The App uses System.Windows.Controls.Canvas to draw a white rectangle on a black background.该应用程序使用System.Windows.Controls.Canvas在黑色背景上绘制一个白色矩形。

I've troubles with the keyboard-related events.我遇到了与键盘相关的事件的麻烦。

Full source is the following完整来源如下

using System;
using System.Drawing;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Forms.Integration;
using Brushes = System.Windows.Media.Brushes;
using Panel = System.Windows.Forms.Panel;
using Rectangle = System.Windows.Shapes.Rectangle;
using UserControl = System.Windows.Controls.UserControl;

namespace WpfHostApp
{
    internal static class Program
    {
        /// <summary>
        /// Entry point.
        /// </summary>
        [STAThread]
        private static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            var panel = new Panel { Dock = DockStyle.Fill };

            var form = new Form {Size = new Size(800, 600), Text = "WPF Host Form"};
            form.Controls.Add(panel);

            var rectangle = new Rectangle {Fill = Brushes.White, Width = 100, Height = 100};

            var canvas = new Canvas {Background = Brushes.Black};
            canvas.Children.Add(rectangle);

            var userControl = new UserControl {Content = canvas};

            var elementHost = new ElementHost {Child = userControl, Dock = DockStyle.Fill};

            panel.Controls.Add(elementHost);

            form.KeyDown += (sender, args) => MessageBox.Show("Key pressed!");

            Application.Run(form);
        }
    }
}

The form.KeyDown event won't fire (practically form.Key* won't fire), but if I comment the line panel.Controls.Add(elementHost); form.KeyDown事件不会触发(实际上form.Key*不会触发),但是如果我评论该行panel.Controls.Add(elementHost); the event fires but obviously no canvas is drawn.事件触发但显然没有绘制画布。

I can't see what in the example code above could cause this issue.我看不出上面的示例代码中是什么导致了这个问题。 What could be the culprit?罪魁祸首可能是什么?

EDIT:编辑:

I've added a recursive function for suscribing KeyDown... no results我添加了一个递归函数来订阅 KeyDown ......没有结果

In Main() , after form.KeyDown :Main() ,在form.KeyDown之后:

foreach (Control control in form.Controls)
{
    SuscribeKeyDown(control);
}

SuscribeKeyDown(Control control) function: SuscribeKeyDown(Control control)功能:

private static void SuscribeKeyDown(Control control)
{
    control.KeyDown += (sender, args) => MessageBox.Show("Key pressed!");
    foreach (Control controlNested in control.Controls)
    {
        SuscribeKeyDown(controlNested);
    }
}

Set canvas.Focusable to true and catch the KeyDown event of the canvas:canvas.Focusable设置为true并捕获画布的KeyDown事件:

[STAThread]
private static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    var panel = new System.Windows.Forms.Panel { Dock = DockStyle.Fill };

    var form = new Form { Size = new Size(800, 600), Text = "WPF Host Form" };
    form.Controls.Add(panel);

    var rectangle = new System.Windows.Shapes.Rectangle { Fill = System.Windows.Media.Brushes.White, Width = 100, Height = 100 };

    var canvas = new Canvas { Background = System.Windows.Media.Brushes.Black,
        Focusable = true};
    canvas.Children.Add(rectangle);

    var userControl = new System.Windows.Controls.UserControl { Content = canvas };

    var elementHost = new ElementHost { Child = userControl, Dock = DockStyle.Fill };

    panel.Controls.Add(elementHost);

    // form.KeyDown += (sender, args) => MessageBox.Show("Key pressed!");
    canvas.KeyDown += (sender, args) => MessageBox.Show("Key pressed!");

    Application.Run(form);
}

Make sure the control is selected and has the focus确保控件被选中并具有焦点

MyWinformChild.Select();
if(MyWinformChild.Focus())

Hook on LostFocus to keep it selected or simply to know when it happens挂在 LostFocus 上以保持选中状态或只是知道它何时发生

MyWinformChild.LostFocus += MyWinformChild_LostFocus;

You should set the form's KeyPreview field to true .您应该将表单的KeyPreview字段设置为true Then your form's KeyDown event will work.然后您的表单的KeyDown事件将起作用。

Add to Form TabControl and put ElementHost to TabPage.添加到表单 TabControl 并将 ElementHost 放到 TabPage。 And now KeyDown/KeyUp will be work.现在 KeyDown/KeyUp 将起作用。 Not the best practice, but it works.不是最佳实践,但它有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM