Win Forms UserControl未检测到按键

时间:2016-08-16 17:20:16

标签: c# .net winforms user-controls

关于此问题有很多问题(onetwothreefourfive),但我尝试了所有问题他们要么不工作,要么不适合我的目的。这是我的基本结构:

User Control
|-Panel
  |-Picture Box (several of them, created at runtime, do not exist at design time)

因为我认为这是相关的,所以小组的码头设置为"填充"并调整大小设置为"增长和缩小",因此它始终涵盖整个用户控件。 PictureBoxes总是覆盖面板的一部分,但通常不是全部(尽管有可能)。

我专门听Ctrl + C,我需要一个能够响应的方法,无论哪个孩子有焦点。我喜欢一种可以听任意按键的方法,所以我可以稍后再进行扩展。

链接页面上的答案之一建议为这些按键创建一个全球聆听者,我不想这样做,因为如果它是后台应用程序,我不想让它关闭。另一个建议以顶级形式检测它并将其过滤到我的用户控件。问题是,关闭时的用户控件正在构建为DLL,并且我不想强制使用它的应用程序必须实现对Ctrl + C的监听,这应该是它应该是自己处理。

为什么上面的链接对我不起作用

1)我的UserControl上没有KeyPreview属性设置为true。关于那个问题的第二个答案建议覆盖ProcessCmdKey,我做了,但无论我尝试什么,都不会调用回调。

2)这个也建议重写ProcessCmdKey。正如我所说,它永远不会被称为。

3)我没有接受按钮设置为true。

4)KeyDownPreviewKeyDown回调都已实现,均未被调用。

5)同时建议使用ProcessCmdKey。

如何在用户控制级别检测关键事件而不管焦点?或者,如果我尝试的上述方法应该正常工作,我错过了什么设置阻止它工作?

2 个答案:

答案 0 :(得分:3)

在具有焦点的控件上触发击键事件。你选择了不喜欢聚焦的控件,没有显示焦点,也没有使用按键本身。哪个问题的问题是你的应用用户可能知道 Ctrl + C将会做什么。

我假设Ctrl + C应该将PictureBox中的图像复制到剪贴板。所以最好的办法是从PB派生自己的类并修改它,以便可以选择并显示焦点。在项目中添加一个新类并粘贴下面显示的代码。编译。将其从工具箱顶部拖动,替换用户控件中的PB。

using System;
using System.Windows.Forms;
using System.Drawing;

class SelectablePictureBox : PictureBox {
    public SelectablePictureBox() {
        this.SetStyle(ControlStyles.Selectable, true);
        this.TabStop = true;
    }
    protected override void OnMouseDown(MouseEventArgs e) {
        if (e.Button == MouseButtons.Left) this.Focus();
        base.OnMouseDown(e);
    }
    protected override void OnEnter(EventArgs e) {
        this.Invalidate();
        base.OnEnter(e);
    }
    protected override void OnLeave(EventArgs e) {
        this.Invalidate();
        base.OnLeave(e);
    }
    protected override void OnPaint(PaintEventArgs e) {
        base.OnPaint(e);
        if (this.Focused) {
            var rc = this.DisplayRectangle;
            rc.Inflate(new Size(-2, -2));
            ControlPaint.DrawFocusRectangle(e.Graphics, rc);
        }
    }
}

答案 1 :(得分:1)

  

OP:我专门听Ctrl + C,我需要一个可以的方法   无论哪个孩子有焦点,都会做出回应。

如果你想从你的控件中处理一个键组合,如 Ctrl + C ,即使它没有焦点或者它不可选,你可以添加一个不可见的MenuStrip到您的用户控件并向其添加项目并为其分配快捷方式。然后处理项目的点击事件并做你需要的事情。

每次用户按 Ctrl + C 时,即使您的控件不包含焦点,也会引发click事件。

您也可以使用代码执行此操作:

public UserControl1()
{
    InitializeComponent();
    var menu = new MenuStrip();
    var item = new ToolStripMenuItem();
    item.ShortcutKeys = System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C;
    item.Click += item_Click;
    menu.Items.Add(item);
    menu.Visible = false;
    this.Controls.Add(menu);
}
void item_Click(object sender, EventArgs e)
{
    MessageBox.Show("Ctrl + C");
}

注意

如果没有焦点,您无法处理关键事件,但使用MenuStrip可以使用上述方法捕获您想要的快捷键。

使其有效的原因是Form ContainerControl ContainerControl调用ToolStripManager.ProcessCmdKey ProcessCmdKey方法导致所有非处理快捷方式上下文ToolStripManager的条带 有关详细信息,请查看ContainerControl.ProcessCmdKey的{​​{3}}。