在组件上画线 [英] draw line on a component
问题描述
我有一个包含 2 列的表格,在其中一列中我有一个由我创建的组件.我想在这张表中画一条线放在前面,但是当我尝试使用我发布的代码时,这条线在我创建的另一个组件后面
I have a table with 2 columns, in one of these columns I have a component created by me. I would like to draw a line in this table bring to front, but when I try with the code I post, the line goes behind the other component I created
public void CoTableLayoutPanel2_Paint(object sender, PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.FillRectangle(new SolidBrush(Color.Black), 0, 50, this.Width, 1);
}
推荐答案
下面是一个组合图形的例子,让所有嵌套控件绘制它们的图形部分自己.
Here is an example of composing the graphics by letting all nested controls draw their part of the graphics onto themselves.
诀窍是让他们都参与并移动 Graphics
以使合成无缝.
The trick is to make them all participate and shift the Graphics
to make the composite seamless.
请注意,并非所有控件都正确支持 Paint
事件;最值得注意的是遗留的 TextBox
不会一起玩..
Note that not all controls support the Paint
event properly; most notably the legacy TextBox
will not play along..
为了让它工作,我创建了一个类来存储图形数据;这很简单.对于更多涉及的东西,可以简单地扩展它..:
To make it work I create a class to store the graphics data; it is quite simplistic. For more involved stuff one can simply expand it..:
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
的代码.它包含一些控件,包括一个带有 Radiobutton
的 GroupBox
,以表明深度嵌套的控件仍然有效.
I won't show code for the UserObject
. It contains a few controls including a GroupBox
with a Radiobutton
in it to show that deeply nested controls still work.
该类有一个可以调用的 Draw
方法,传入一个有效的 Graphics
对象.
The class has a Draw
method which one can call, passing in a valid Graphics
object.
要初始化,我们使用以下代码:
To initialize we use this code:
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 将 Paint
事件连接到所有控件.
I use a lambda to hook up the Paint
events to all controls.
该方法是递归以捕获公共父控件中的所有控件.
The method is recursive to catch all controls inside a common parent control.
这是图形列表..
List<DrawAction> drawings = new List<DrawAction>();
及其初始化:
..
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);
这是结果和设计器视图:
This is the result and the designer view:
您可以看到 TextBoxes
没有播放;还有 GroupBoxes
的一个小故障,不知道为什么..
You can see that the TextBoxes
don't play along; also that there is a tiny glitch with the GroupBoxes
, not sure why..
这篇关于在组件上画线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!