KeyDown,KeyUp和KeyPressed不会在托管WPF控件的WinForms应用程序上启动

时间:2014-07-08 19:18:19

标签: c# .net wpf winforms events

我在针对.NET 4.5的C#中测试了WinForms APP。该应用程序使用System.Windows.Controls.Canvas在黑色背景上绘制白色矩形。

我遇到与键盘相关的事件。

完整来源如下

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);
        }
    }
}

form.KeyDown事件不会触发(实际上form.Key*不会触发),但如果我对行panel.Controls.Add(elementHost);发表评论,则事件会触发,但显然不会绘制画布。

我无法看到上面示例代码中的内容可能会导致此问题。可能是罪魁祸首?

编辑:

我添加了一个递归函数来伪造KeyDown ...没有结果

Main()之后的form.KeyDown

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

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);
    }
}

4 个答案:

答案 0 :(得分:1)

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);
}

答案 1 :(得分:0)

您应该将表单的KeyPreview字段设置为true。然后,您的表单的KeyDown事件将起作用。

答案 2 :(得分:0)

添加到窗体TabControl并将ElementHost放到TabPage。现在KeyDown / KeyUp将可以使用。 这不是最佳做法,但可以。

答案 3 :(得分:0)

确保已选中控件并具有焦点

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

使用LostFocus保持选中状态,或者只是知道它何时发生

MyWinformChild.LostFocus += MyWinformChild_LostFocus;