在表单中的所有控件上方绘制线条
我正在开发一个程序。在这里,我有一个表单,其中包含表单上的按钮和标签等控件。
现在我使用DrawLine()方法在表单上绘制一条线,但这条线出现在所有控件的背景中,如标签和按钮。
我想画线,在所有控件之上,以便它不会隐藏在其他控件的背景中。
我该怎么办?
Hi,
I am developing a program. In this, i have a form with some controls like Button and Labels on the form.
Now i draw a line on the form using DrawLine() method but this line appears in the backgrounds of all the controls like labels and Buttons.
I want to draw line, above all the controls so that it does not hidden in the backgrounds of other controls.
how can i do it?
从技术上讲,你不能。在控件顶部绘制任何东西并不是任何人都希望你想做的事情,可能是因为它有点难看!
但是,它有可能 - 你只需要使用kludge。
在表单加载事件中,添加:
Technically speaking, you can't. Drawing anything over the top of controls is not something anyone expected you would want to do, probably because it is kinda ugly!
But, it is possible - you just have to use a kludge.
In your form load event, add:
Panel pan = new Panel();
pan.Enabled = false;
pan.Width = Width;
pan.Height = 1;
pan.Location = new Point(0, 90);
pan.BackColor = Color.Red;
Controls.Add(pan);
pan.BringToFront();
这将在你的表格上方的contyrols顶部放一个像素的高线,并且不会干扰鼠标操作。
你需要调整大小如果表格尺寸发生变化,请参阅面板。
谢谢老兄,但这只会创建一条水平线。我想创建
对角线。我能做到吗?
是的。但它更糟糕,更糟糕。 (两者都要看和做)
你要做的是为面板创建一个非零宽度的区域...
This will put a one pixel high line across your form over the top of contyrols, and will not interfere with mouse operations.
You will need to resize the panel if the form size changes.
"Thanks dude, but this will only create a horizontal line. i want to create
diagonal line. can i do it?"
Yes. But it's much, much, nastier. (Both to look at and to do)
What you have to do is create a non-zero width region for the panel...
Panel pan = new Panel();
pan.Enabled = false;
pan.Width = Width;
pan.Height = Height;
pan.BackColor = Color.Red;
Point[] points = {new Point(0, 0),
new Point(1, 0),
new Point(Width, Height - 1),
new Point(Width, Height) ,
new Point(Width - 1, Height),
new Point(0, 1) };
GraphicsPath gp = new GraphicsPath();
gp.AddLines(points);
pan.Region = new System.Drawing.Region(gp);
Controls.Add(pan);
pan.BringToFront();
这是一个功能齐全的类。它不仅可以绘制一条线,还可以绘制一个曲折。
如果你想要一条线,只需绘制一个2点的曲折。
This is a fully functional class. It helps draw not only a line, but a zigzag.
If you want a line, just draw a zigzag with 2 points.
public class ZigzagControl : Control
{
Point[] _points;
PointF[] _leftpoints;
PointF[] _rightpoints;
PointF[] _boundpoints;
int _thickness;
int _pointnum;
public ZigzagControl(Point[] points, int thickness = 1)
{
_points = points;
_thickness = thickness;
_pointnum = _points.Length;
LineColor = Color.Black;
_leftpoints = new PointF[_pointnum];
_rightpoints = new PointF[_pointnum];
CalcBoundPoints();
CalcControlSizeAndLocation();
}
private void CalcFirstPointPair()
{
float u0, v0, p0, q0;
double x0, y0, x1, y1;
double dx, dy, l;
double w = _thickness;
x0 = _points[0].X;
y0 = _points[0].Y;
x1 = _points[1].X;
y1 = _points[1].Y;
dx = x1-x0;
dy = y1-y0;
l = Math.Sqrt(dx*dx + dy*dy);
u0 = (float)(x0 + w * dy / l);
v0 = (float)(y0 - w * dx / l);
_leftpoints[0] = new PointF(u0, v0);
p0 = (float)(x0 - w * dy / l);
q0 = (float)(y0 + w * dx / l);
_rightpoints[0] = new PointF(p0, q0);
}
private void CalcMidlePointPair(int pairIndex)
{
float u, v, p, q;
double u1, v1, u2, v2;
double p1, q1, p2, q2;
double x1, y1, x2, y2, x3, y3;
double dx, dy, l;
double a11, a12, b1;
double a21, a22, b2;
double det, det1, det2;
double w = _thickness;
x1 = _points[pairIndex-1].X;
y1 = _points[pairIndex-1].Y;
x2 = _points[pairIndex].X;
y2 = _points[pairIndex].Y;
x3 = _points[pairIndex+1].X;
y3 = _points[pairIndex+1].Y;
dx = x2 - x1;
dy = y2 - y1;
l = Math.Sqrt(dx * dx + dy * dy);
u1 = x1 + w * dy / l;
v1 = y1 - w * dx / l;
a11 = y2 - y1;
a12 = -(x2 - x1);
b1 = (y2 - y1) * u1 - (x2 - x1) * v1;
dx = x3 - x2;
dy = y3 - y2;
l = Math.Sqrt(dx * dx + dy * dy);
u2 = x2 + w * dy / l;
v2 = y2 - w * dx / l;
a21 = y3 - y2;
a22 = -(x3 - x2);
b2 = (y3 - y2) * u2 - (x3 - x2) * v2;
det = a11 * a22 - a21 * a12;
det1 = b1 * a22 - b2 * a12;
det2 = a11 * b2 - a21 * b1;
u = (float)(det1 / det);
v = (float)(det2 / det);
_leftpoints[pairIndex] = new PointF(u, v);
dx = x2 - x1;
dy = y2 - y1;
l = Math.Sqrt(dx * dx + dy * dy);
p1 = x1 - w * dy / l;
q1 = y1 + w * dx / l;
a11 = y2 - y1;
a12 = -(x2 - x1);
b1 = (y2 - y1) * p1 - (x2 - x1) * q1;
dx = x3 - x2;
dy = y3 - y2;
l = Math.Sqrt(dx * dx + dy * dy);
p2 = x2 - w * dy / l;
q2 = y2 + w * dx / l;
a21 = y3 - y2;
a22 = -(x3 - x2);
b2 = (y3 - y2) * p2 - (x3 - x2) * q2;
det = a11 * a22 - a21 * a12;
det1 = b1 * a22 - b2 * a12;
det2 = a11 * b2 - a21 * b1;
p = (float)(det1 / det);
q = (float)(det2 / det);
_rightpoints[pairIndex] = new PointF(p, q);
}
private void CalcLastPointPair()
{
float un, vn, pn, qn;
double xn, yn, xn_1, yn_1;
double dx, dy, l;
double w = _thickness;
int n = _pointnum-1;
xn = _points[n].X;
yn = _points[n].Y;
xn_1 = _points[n-1].X;
yn_1 = _points[n-1].Y;
dx = xn_1-xn;
dy = yn_1-yn;
l = Math.Sqrt(dx*dx + dy*dy);
pn = (float)(xn + w * dy / l);
qn = (float)(yn - w * dx / l);
_rightpoints[n] = new PointF(pn, qn);
un = (float)(xn - w * dy / l);
vn = (float)(yn + w * dx / l);
_leftpoints[n] = new PointF(un, vn);
}
private void CalcBoundPoints()
{
int i;
CalcFirstPointPair();
for (i = 1; i < _pointnum - 1; i++) CalcMidlePointPair(i);
CalcLastPointPair();
int j=0;
int n = 2*_pointnum + 1;
_boundpoints = new PointF[n];
for (i = 0; i < _pointnum; i++)
{
_boundpoints[j] = _leftpoints[i];
j++;
}
for (i = _pointnum - 1; i >= 0; i--)
{
_boundpoints[j] = _rightpoints[i];
j++;
}
_boundpoints[n - 1] = _leftpoints[0];
}
private void CalcControlSizeAndLocation()
{
float minX, minY, maxX, maxY;
minX = maxX = _leftpoints[0].X;
minY = maxY = _leftpoints[0].Y;
int n = _boundpoints.Length;
for (int i = 0; i < n; i++)
{
if (_boundpoints[i].X < minX) minX = _boundpoints[i].X;
if (_boundpoints[i].X > maxX) maxX = _boundpoints[i].X;
if (_boundpoints[i].Y < minY) minY = _boundpoints[i].Y;
if (_boundpoints[i].Y > maxY) maxY = _boundpoints[i].Y;
}
int width = (int)Math.Ceiling(maxX - minX);
int height = (int)Math.Ceiling(maxY - minY);
this.Size = new Size(width, height);
this.Location = new Point((int)minX, (int)minY);
for (int i = 0; i < n; i++)
{
_boundpoints[i].X -= minX;
_boundpoints[i].Y -= minY;
}
}
protected override void OnPaint(PaintEventArgs e)
{
GraphicsPath graphicsPath = new GraphicsPath();
graphicsPath.AddLines(_boundpoints);
this.Region = new Region(graphicsPath);
}
public Color LineColor
{
get
{
return BackColor;
}
set
{
if (value == BackColor) return;
BackColor = value;
}
}
public int Thickness
{
get
{
return _thickness;
}
set
{
if (value == _thickness) return;
_thickness = value;
CalcBoundPoints();
CalcControlSizeAndLocation();
Invalidate();
}
}
}