我有一个带有其他控件的面板。 我想在它上面画一条线,并在面板中所有控件的顶部显示。
我发现了3种解决方案(没有一种能按照我想要的方式工作):
1. 获取桌面 DC 并在屏幕上绘制。 如果它们重叠窗体,则会在其他应用程序上绘制。
2. 重写面板的 "CreateParams":
3. 在面板上使用 Graphics 绘图。
=
protected override CreateParams CreateParams {
get {
CreateParams cp;
cp = base.CreateParams;
cp.Style &= ~0x04000000; //WS_CLIPSIBLINGS
cp.Style &= ~0x02000000; //WS_CLIPCHILDREN
return cp;
}
}
//注意,我也尝试禁用WS_CLIPSIBLINGS并在OnPaint()中绘制线条。但是...由于面板的OnPaint在其中的控件的OnPaint之前被调用,因此内部控件的绘制仅会在线条上方绘制。
我看到有人建议使用消息过滤器来侦听WM_PAINT消息,并使用计时器,但我认为这个解决方案既不是“良好的实践”,也不是有效的解决方案。
你会怎么做?决定控件内部完成绘制后X毫秒,然后将计时器设置为X毫秒吗?
这个屏幕截图显示了关闭WS_CLIPSIBLINGS和WS_CLIPCHILDREN的面板。
蓝色线条是在Panel的OnPaint中绘制的,只是被文本框和标签绘制。
红色线条之所以在顶部绘制,是因为它不是从面板的OnPaint中绘制的(实际上是由于点击按钮而绘制的)。
第三步:创建一个透明层并在该层上绘制。 我使用以下方法创建了一个透明控件:
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
return cp;
}
}
问题仍然存在,即将透明控件放在面板及其所有控件的顶部。 我尝试使用 "BringToFront()" 将其置于最前面,但似乎没有帮助。 我将其放在了 Line 控件的 OnPaint() 处理程序中。 我应该尝试把它放在别的地方吗? - 这也会导致在面板上方有另一个控件时出现问题。(捕捉鼠标点击等。)
任何帮助都将不胜感激!
**编辑: 黑色线条是我尝试做的示例。(使用 Windows 绘图工具进行绘制)