C# 在元件上画线

C# 在元件上画线,c#,winforms,C#,Winforms,我有一个包含两列的表,在其中一列中有一个由我创建的组件。我想在这个表中画一条线放在前面,但是当我尝试使用我发布的代码时,这条线会在我创建的另一个组件后面 public void CoTableLayoutPanel2_Paint(object sender, PaintEventArgs e) { base.OnPaint(e); e.Graphics.FillRectangle(new SolidBrush(Color.Black), 0, 50, t

我有一个包含两列的表,在其中一列中有一个由我创建的组件。我想在这个表中画一条线放在前面,但是当我尝试使用我发布的代码时,这条线会在我创建的另一个组件后面

 public void CoTableLayoutPanel2_Paint(object sender, PaintEventArgs e)
    {
        base.OnPaint(e);
        e.Graphics.FillRectangle(new SolidBrush(Color.Black), 0, 50, this.Width, 1);

    }
下面是一个通过让所有嵌套控件将其图形部分绘制到自己身上来组合图形的示例

诀窍是让他们全部参与,并改变图形以使合成无缝

请注意,并非所有控件都正确支持绘制事件;最值得注意的是,传统的文本框将无法播放

为了让它工作,我创建了一个类来存储图形数据;这太简单了。对于更复杂的内容,您可以简单地扩展它..:

public class DrawAction
{
    public Point p1 { get; set; }
    public Point p2 { get; set; }
    public Color c1 { get; set; }
    public int mode { get; set; }

    public DrawAction(Point p1_, Point p2_, Color c_, int mode_)
    {
        p1 = p1_; p2 = p2_; c1 = c_; mode = mode_;
    }

    public void Draw(Graphics g)
    {
        switch (mode)
        {
            case 0: // line
                using (Pen pen = new Pen(c1)) 
                  g.DrawLine(pen, p1, p2);
                break;
            case 1: // rectangle
                using (Pen pen = new Pen(c1)) 
                  g.DrawRectangle(pen, p1.X, p1.Y, p2.X - p1.X, p2.Y - p1.Y);
                break;
            case 2: // filled rectangle
                using (SolidBrush brush = new SolidBrush(c1)) 
                  g.FillRectangle(brush, p1.X, p1.Y, p2.X - p1.X, p2.Y - p1.Y);
                break;
            default:
                break;
        }
    }
}
我不会显示UserObject的代码。它包含一些控件,包括一个GroupBox,其中有一个单选按钮,用于显示嵌套较深的控件仍然有效

这个类有一个Draw方法,可以调用它,传入一个有效的图形对象

要初始化,我们使用以下代码:

void initPainting(Control parent, Control baseCtl)
{
    foreach (Control ctl in parent.Controls)
    {
        ctl.Paint += (s, e) =>
        {
            foreach (var drawing in drawings)
            {
                Point offset = 
                     baseCtl.PointToClient(ctl.PointToScreen(Point.Empty));

                Graphics g = e.Graphics;
                g.TranslateTransform(-offset.X, -offset.Y);
                drawing.Draw(g);
                g.ResetTransform();

            }
        };
        initPainting(ctl, baseCtl);  // recursion
    }
}
我使用lambda将绘制事件连接到所有控件

该方法是递归的,用于捕获公共父控件内的所有控件

这是图形列表

 List<DrawAction> drawings = new List<DrawAction>();
这是结果和设计器视图:


你可以看到文本框不起作用;此外,GroupBox也有一个小问题,不知道为什么。

您需要在组件顶部安装一个透明面板,以便在上面画线。当您在承载组件的面板上绘图时,绘图将位于您发现的面板的任何子控件下面。您的目标是什么:Winforms、WPF、ASP。。?您应该始终正确标记您的问题,以便人们可以在问题页面上看到它!如果足够小心,您还可以尝试在父控件和希望线交叉的控件上绘制补丁。这对于一些控件(如标签)来说很简单,但对于其他控件就不那么简单了。@500您尝试过吗?透明度仅适用于嵌套控件,但面板将不会嵌套在组件内的控件中。@Mrpit:组件中有哪些类型的控件以及它们的嵌套深度?
    ..
    InitializeComponent();
    Size sz = tableLayoutPanel1.Size;
    drawings.Add(
      new DrawAction(Point.Empty, new Point(sz.Width, sz.Height), Color.Red, 0));
    drawings.Add(
      new DrawAction(new Point(0, sz.Height), new Point(sz.Width, 0), Color.Blue, 0));
    drawings.Add(
      new DrawAction(new Point(50, 50), new Point(300, 300), Color.Green, 1));

    initPainting(tableLayoutPanel1, tableLayoutPanel1);