我有一个UserControl
,其中包含一些其他控件,然后是一个Panel
,用于在鼠标事件上绘制自定义形状。我想添加一些其他功能,但为此我需要检测KeyDown
和KeyUp
,同时鼠标在Panel上绘制形状(在这种情况下UserControl.KeyDown/KeyUp
永远不会触发)。怎么能实现这个目标?
修改
以下是UserControl的最低版本,可以看到问题:
public partial class UserControl1 : UserControl
{
TextBox textBox1;
Panel panel1;
public UserControl1()
{
InitializeComponent();
textBox1 = new System.Windows.Forms.TextBox();
textBox1.Location = new System.Drawing.Point(0, 0);
this.Controls.Add(this.textBox1);
panel1 = new System.Windows.Forms.Panel();
panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
panel1.Location = new System.Drawing.Point(0, 25);
panel1.Size = new System.Drawing.Size(300, 150);
panel1.MouseEnter += new System.EventHandler(this.panel1_MouseEnter);
this.Controls.Add(this.panel1);
this.Size = new System.Drawing.Size(300, 200);
this.KeyDown += UserControl1_KeyDown;
}
private void panel1_MouseEnter(object sender, EventArgs e)
{
panel1.Focus();
}
void UserControl1_KeyDown(object sender, KeyEventArgs e)
{
MessageBox.Show("Key down");
}
}
当此控件位于表单内时,"键向下"消息永远不会显示。
答案 0 :(得分:0)
我从Hans Passant here获取了代码(很好的提示,非常感谢!)我修改了它以满足我的需求,如下所示:
class SelectablePanel : Panel
{
public SelectablePanel()
{
this.SetStyle(ControlStyles.Selectable, true);
this.TabStop = true;
}
protected override bool IsInputKey(Keys keyData)
{
if (keyData == Keys.Up || keyData == Keys.Down) return true;
if (keyData == Keys.Left || keyData == Keys.Right) return true;
return base.IsInputKey(keyData);
}
protected override void OnKeyDown(KeyEventArgs e)
{
var handler = KeyDown;
if (handler != null) handler(this, e);
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
var handler = KeyPress;
if (handler != null) handler(this, e);
}
protected override void OnKeyUp(KeyEventArgs e)
{
var handler = KeyUp;
if (handler != null) handler(this, e);
}
protected override void OnMouseEnter(EventArgs e)
{
this.Focus();
base.OnMouseEnter(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 pe)
{
base.OnPaint(pe);
if (this.Focused)
{
var rc = this.ClientRectangle;
rc.Inflate(-2, -2);
ControlPaint.DrawFocusRectangle(pe.Graphics, rc);
}
}
[Browsable(true)]
public new event EventHandler<KeyEventArgs> KeyDown;
[Browsable(true)]
public new event EventHandler<KeyEventArgs> KeyUp;
[Browsable(true)]
public new event EventHandler<KeyPressEventArgs> KeyPress;
}
最后我修改了我的原始代码:
public partial class UserControl1 : UserControl
{
TextBox textBox1;
SelectablePanel selectablePanel;
public UserControl1()
{
InitializeComponent();
textBox1 = new System.Windows.Forms.TextBox();
textBox1.Location = new System.Drawing.Point(0, 0);
this.Controls.Add(this.textBox1);
selectablePanel = new SelectablePanel();
selectablePanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
selectablePanel.Location = new System.Drawing.Point(0, 25);
selectablePanel.Size = new System.Drawing.Size(300, 150);
selectablePanel.KeyDown += panel1_KeyDown;
this.Controls.Add(this.selectablePanel);
this.Size = new System.Drawing.Size(300, 200);
}
void panel1_KeyDown(object sender, KeyEventArgs e)
{
MessageBox.Show("Key down");
}
}
现在它适用于我需要的东西。