我的UserControl
包含另一个UserControl
。我希望包含控件能够处理在包含的控件区域内发生的任何鼠标事件。最简单的方法是什么?
可以更改所包含控件的代码,但这只是最后的手段。包含的控件有一个由非托管库控制的窗口。
FWIW,我尝试为包含控件的鼠标事件添加处理程序,但这些处理程序永远不会被调用。我怀疑所包含的控件正在消耗鼠标事件。
我考虑在包含的控件之上添加某种透明窗口,以捕获事件,但我仍然是Windows Forms的新手,我想知道是否有更好的方法。
答案 0 :(得分:1)
如果内部控件未密封,您可能希望将其子类化并覆盖与鼠标相关的方法:
protected override void OnMouseClick(MouseEventArgs e) {
//if you still want the control to process events, uncomment this:
//base.OnMouseclick(e)
//do whatever
}
等
答案 1 :(得分:1)
嗯,这在技术上是可行的。您必须自己重定向鼠标消息,这需要一点P / Invoke。将此代码粘贴到内部UserControl类中:
protected override void WndProc(ref Message m) {
// Re-post mouse messages to the parent window
if (m.Msg >= 0x200 && m.Msg <= 0x209 && !this.DesignMode && this.Parent != null) {
Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
// Fix mouse position to be relative from parent's client rectangle
pos = this.PointToScreen(pos);
pos = this.Parent.PointToClient(pos);
IntPtr lp = (IntPtr)(pos.X + pos.Y << 16);
PostMessage(this.Parent.Handle, m.Msg, m.WParam, lp);
return;
}
base.WndProc(ref m);
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr PostMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
最好避免顺便说一句。父控件应该只是订阅内部控件的鼠标事件。
答案 2 :(得分:0)
这就是我的所作所为:
首先,我定义了一个TransparentControl
类,它只是一个透明的控件,不会绘制任何东西。 (此代码归功于http://www.bobpowell.net/transcontrols.htm。)
public class TransparentControl : Control
{
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
return cp;
}
}
protected override void OnPaint(PaintEventArgs pe)
{
// Do nothing
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
// Do nothing
}
}
然后,我在我的用户控件中放置了一个TransparentControl
在所包含的用户控件之上,并为其鼠标事件添加了处理程序。