如何画线并在Panel中选择它

时间:2015-10-03 07:11:02

标签: c# winforms canvas graphics

我的程序可以使用canvas.Drawline()绘制线条。如何点击线并更改此颜色(选择线)?

private List<Point> coordFirst = new List<Point>();
private List<Point> coordLast = new List<Point>();
public Graphics canvas;

        private void Form1_Load(object sender, EventArgs e)
        {
            canvas=panel1.CreateGraphics();
        }

协调线存储在coordFirs&amp; coodLast。

2 个答案:

答案 0 :(得分:6)

这是一个合适的Line类:

class Line
{
    public Color LineColor { get; set; }
    public float Linewidth { get; set; }
    public bool Selected { get; set; }
    public Point Start { get; set; }
    public Point End { get; set; }

    public Line(Color c, float w, Point s, Point e)
    { LineColor = c; Linewidth = w; Start = s; End = e;    }

    public void Draw(Graphics G)
    { using (Pen pen = new Pen(LineColor, Linewidth)) G.DrawLine(pen, Start, End); }

    public bool HitTest(Point Pt)
    {
        // test if we fall outside of the bounding box:
        if ((Pt.X < Start.X && Pt.X < End.X) || (Pt.X > Start.X && Pt.X > End.X) ||
            (Pt.Y < Start.Y && Pt.Y < End.Y) || (Pt.Y > Start.Y && Pt.Y > End.Y)) 
            return false;
        // now we calculate the distance:
        float dy = End.Y - Start.Y;
        float dx = End.X - Start.X;
        float Z = dy * Pt.X - dx * Pt.Y + Start.Y * End.X - Start.X * End.Y;
        float N = dy * dy + dx * dx;
        float dist = (float)( Math.Abs(Z) / Math.Sqrt(N));
        // done:
        return dist < Linewidth / 2f;
    }

}

为行定义列表,可能在类级别:

    List<Line> lines = new List<Line>();

以下是几行初始化的方法:

for (int i = 0; i < 20; i++) lines.Add(new Line(Color.Black, 4f, 
    new Point(R.Next(panel1.Width), R.Next(panel1.Height)), 
    new Point(R.Next(panel1.Width), R.Next(panel1.Height))));

以下是点击十字路口的结果:

enter image description here

每当您添加,更改或删除一行时,您需要通过触发Panel事件使Paint反映新闻:

panel1.Invalidate();

以下是Paint的{​​{1}}事件:

Panel

private void panel1_Paint(object sender, PaintEventArgs e) { e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; foreach (Line L in lines) L.Draw(e.Graphics); } 事件中,您进行了测试:

MouseClick

为避免闪烁,请不要使用基本的private void panel1_MouseClick(object sender, MouseEventArgs e) { foreach(Line L in lines) L.LineColor = L.HitTest(e.Location) ? Color.Red : Color.Black; panel1.Invalidate(); } 课程,因为它不是Panel。而是使用doublebufferedPictureBox子类:

doublebuffered Panel

备注

  • 没有&#39; Line&#39;在WinForms中,只有各种颜色的像素。因此,要选择一条线,您需要存储它的两个端点&#39;坐标,然后找出你点击时是否点击它。

  • 以上示例显示了如何在数学中执行此操作。

  • 相反,可以通过将每条线绘制到位图上来测试每条线并测试鼠标单击的像素。但绘制这些位图也必须在幕后进行数学运算,并为位图分配空间,因此数学效率会更高。

  • 是的,class DrawPanel : Panel { public DrawPanel () { DoubleBuffered = true; } } 类对于这么简单的事情看起来有点长,但看看现在所有的事件代码有多短!这是因为 Responsiblities 是他们所属的地方!

  • 另请注意,在WinForms中执行任何绘图的第一条规则是:从不缓存或存储Line对象。事实上,你不应该首先使用 Grahics,因为CreateGraphics对象永远不会留在范围内,它产生的图形不会坚持(即在最小化最大化序列中存活下来)..

  • 另请注意我将<{1}}个参数的Graphics对象>传递给e.Graphics个实例,以便他们可以用当前的Paint对象绘制自己!

  • 要选择更细的线条,可能有助于稍微修改距离检查..

  • 数学直接来自Wikipedia

答案 1 :(得分:-1)

您可以在点击时更改所有内容的颜色。通过使用特定对象的点击事件。

我给你一个按钮的例子。如果单击按钮,则会更改panal的颜色。您可以根据自己的要求修改代码。

private List<Point> coordFirst = new List<Point>();
    private List<Point> coordLast = new List<Point>();
    public Graphics canvas;



    private void Form1_Load(object sender, EventArgs e)
    {
        canvas = panel1.CreateGraphics();
    }





    private void panel1_Click(object sender, EventArgs e)
    {
        panel1.BackColor = Color.Blue;
    }

    private void nonSelectableButton3_Click(object sender, EventArgs e)
    {
        panel1.BackColor = Color.BurlyWood;
    }