关于此问题有很多问题(one,two,three,four,five),但我尝试了所有问题他们要么不工作,要么不适合我的目的。这是我的基本结构:
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)KeyDown
和PreviewKeyDown
回调都已实现,均未被调用。
5)同时建议使用ProcessCmdKey。
如何在用户控制级别检测关键事件而不管焦点?或者,如果我尝试的上述方法应该正常工作,我错过了什么设置阻止它工作?
答案 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}}。