c# - 在面板内的控件之上绘图 (C# WinForms)

标签 c# .net winforms

我知道这个问题已经被问过不止几次了,但到目前为止我还没有找到一个好的解决方案。

我有一个带有其他控件的面板。
我想在它上面和面板中所有控件的顶部画一条线

我遇到了 3 种类型的解决方案(没有一种按照我想要的方式工作):

  1. 获取桌面DC并在屏幕上绘制。
    如果它们与表格重叠,这将利用其他应用程序。

  2. 覆盖面板的“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 绘制的(它实际上是由于单击按钮而绘制的)
alt text


第三:创建一个透明层并在该层的顶部绘图。
我使用以下方法创建了一个透明控件:

protected override CreateParams CreateParams {  
  get {  
    CreateParams cp = base.CreateParams;  
    cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT  
    return cp;  
  }  
}

问题依旧,将透明控件放在Panel及其所有控件之上。
我试过使用“BringToFront()”将它放在最前面,但它似乎没有帮助。
我已将它放在 Line 控件的 OnPaint() 处理程序中。
我应该试着把它放在别的地方吗??
- 这也会导致在面板顶部有另一个控件的问题。 (捕捉鼠标点击等。)

如有任何帮助,我们将不胜感激!

**编辑: 黑线是我试图做的事情的样本。 (用windows paint来画)

alt text

最佳答案

事实证明,这比我想象的要容易得多。感谢您不接受我的任何其他答案。下面是创建 Fline 的两步过程(floating line - 抱歉,来晚了):

alt text

第 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/

相关文章:

c# - c#中多线程的Datagridview

c# - 如何遍历组合框值列表并选择其中一个

C# .NET 如何在不使用 StringBuilder.ToString() 的情况下将 StringBuilder 转换为字节数组

c# - 您可以截断 GridView 中数据绑定(bind)模板字段的结果吗?

c# - 将数据库表转换为 C# 类的工具

c# - WebBrowser 控件调整大小

.net - 如何识别 DLL 是 Debug 还是 Release 构建(在 .NET 中)

c# - Universal App中的NavigationSevice

c# - 组织 using 指令,重新运行测试?

c# - 在运行时修改 Databound ComboBox