我知道这个问题已经被问过不止几次了,但到目前为止我还没有找到一个好的解决方案。
我有一个带有其他控件的面板。
我想在它上面和面板中所有控件的顶部画一条线
我遇到了 3 种类型的解决方案(没有一种按照我想要的方式工作):
获取桌面DC并在屏幕上绘制。
如果它们与表格重叠,这将利用其他应用程序。覆盖面板的“CreateParams”:
=
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 ms 后完成绘制,将定时器设置为 X ms ?
此屏幕截图显示了 WS_CLIPSIBLINGS 和 WS_CLIPCHILDREN 已关闭的面板。
蓝线是在 Panel 的 OnPaint 上绘制的,并且只是被文本框和标签绘制。
红线被绘制在顶部只是因为它不是从面板的 OnPaint 绘制的(它实际上是由于单击按钮而绘制的)
第三:创建一个透明层并在该层的顶部绘图。
我使用以下方法创建了一个透明控件:
protected override CreateParams CreateParams {
get {
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
return cp;
}
}
问题依旧,将透明控件放在Panel及其所有控件之上。
我试过使用“BringToFront()”将它放在最前面,但它似乎没有帮助。
我已将它放在 Line 控件的 OnPaint() 处理程序中。
我应该试着把它放在别的地方吗??
- 这也会导致在面板顶部有另一个控件的问题。 (捕捉鼠标点击等。)
如有任何帮助,我们将不胜感激!
**编辑: 黑线是我试图做的事情的样本。 (用windows paint来画)
最佳答案
事实证明,这比我想象的要容易得多。感谢您不接受我的任何其他答案。下面是创建 Fline 的两步过程(floating line - 抱歉,来晚了):
第 1 步:向您的项目添加一个 UserControl 并将其命名为“Fline”。将以下内容添加到 using 语句中:
using System.Drawing.Drawing2D;
第 2 步:将以下内容添加到 Fline 的 Resize 事件中:
int wfactor = 4; // half the line width, kinda
// create 6 points for path
Point[] pts = {
new Point(0, 0),
new Point(wfactor, 0),
new Point(Width, Height - wfactor),
new Point(Width, Height) ,
new Point(Width - wfactor, Height),
new Point(0, wfactor) };
// magic numbers!
byte[] types = {
0, // start point
1, // line
1, // line
1, // line
1, // line
1 }; // line
GraphicsPath path = new GraphicsPath(pts, types);
this.Region = new Region(path);
编译,然后将 Fline 拖到您的窗体或面板上。重要提示:默认背景颜色与表单相同,因此将 Fline 的背景颜色更改为红色 或其他明显的颜色(在设计器中)。一个奇怪的问题是,当您在设计器中四处拖动它时,它会显示为实心 block ,直到您释放它 - 没什么大不了的。
此控件可以出现在任何其他控件的前面或后面。如果将 Enabled 设置为 false,它仍然可见,但不会干扰下方控件上的鼠标事件。
当然,您会希望出于您的目的对其进行增强,但这显示了基本原理。您可以使用相同的技术来创建您喜欢的任何形状的控件(我对此的初步测试是一个三角形)。
更新:这也是一个很好的密集单行。只需将其放入 UserControl 的 Resize 事件中即可:
this.Region=new Region(new System.Drawing.Drawing2D.GraphicsPath(new Point[]{new Point(0,0),new Point(4,0),new Point(Width,Height-4),new Point(Width,Height),new Point(Width-4,Height),new Point(0,4)},new byte[]{0,1,1,1,1,1}));
关于c# - 在面板内的控件之上绘图 (C# WinForms),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/282838/