如何在winforms c#中绘制通过“节点”连接的多条线?

时间:2016-09-07 12:14:02

标签: c# winforms line graphic

我正在编写dijkstra算法我想在每两个节点之间绘制线条,这两个节点彼此连接两个节点我正在编写代码但它只是在两个节点之间绘制一条线。我想每次点击两个节点它创建了line.of当然,我正在使用"DrawLines()"方法但它只创建一行。

enter image description here

    public class Graph
{
    public Dictionary<int, List<KeyValuePair<int, int>>> vertices = new Dictionary<int, List<KeyValuePair<int, int>>>();

    public void AddVertex(int id, List<KeyValuePair<int, int>> edges)
    {
        if (!vertices.ContainsKey(id))
        {
            vertices.Add(id, new List<KeyValuePair<int, int>>());
        }
        vertices[id].AddRange(edges);
    }

}
    private CircleManager circleManager = new CircleManager();
    private List<Circle> circlesSourceAndDestination = new List<Circle>();
    private Graph g = new Graph();
    private int lastClickedNode = -1;

        public Form1()
    {
        InitializeComponent();
        pictureBox1.Paint += new PaintEventHandler(pic_Paint);
    }

    private void pic_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
        Graphics g = e.Graphics;
        DrawCircles(g);
        DrawLines(g);
    }


    /// <summary>
    /// This method specifies neighbors of node
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private int currentNode = 0;

    private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
    {
        if (e.Button != MouseButtons.Right)
        {
            //Name of node in variable result. for example : 0 or 1 ,...
            var result = circleManager.HitTest(e.Location);

            //node doesn't should be negative
            if (result != -1)
            {
                circlesSourceAndDestination.Add(circleManager.Circles[result]);

                if (lastClickedNode == -1)
                {
                    lastClickedNode = result;
                    return;
                }

                var weigth = CalculateLengthSourceAndDestination(circlesSourceAndDestination);
                circlesSourceAndDestination.Clear();
                if (weigth < 0)
                {
                    weigth *= -1;
                }
                int secondNode = result;
                var neighbor = new KeyValuePair<int, int>(secondNode, weigth);
                var list = new List<KeyValuePair<int, int>> { neighbor };
                g.AddVertex(lastClickedNode, list);

                var nodes = g;
                ExtractNodes(nodes);
                //DrawLines(points);
                lastClickedNode = -1;
            }
        }
        else
        {
            var result = circleManager.HitTest(e.Location);
            if (result != -1)
            {
                circleManager.Circles[circleManager.HitTest(e.Location)].Selected = true;
                circleManager.Circles[result].SelectFillColor = Color.Red;
            }
        }
        pictureBox1.Invalidate();
    }

    private List<Point> pnt = new List<Point>();

    private void ExtractNodes(Graph nodes)
    {
        foreach (var item in nodes.vertices)
        {
            foreach (var circle in circleManager.Circles)
            {
                if (item.Key == Convert.ToInt32(circle.Name) && pnt.Count == 0)
                {
                    pnt.Add(circle.Location);
                }

                ExtractNodesTwo(item.Value);
                if (pnt.Count == 2)
                {
                    return;
                }
            }
        }
    }

    private void ExtractNodesTwo(List<KeyValuePair<int, int>> value)
    {
        if (pnt.Count != 0)
        {
            foreach (var item in circleManager.Circles)
            {
                foreach (var val in value)
                {
                    if (val.Key == Convert.ToInt32(item.Name))
                    {
                        pnt.Add(item.Location);
                    }
                }

                if (pnt.Count == 2)
                    return;
            }
        }
    }

    private void DrawLines(Graphics g)
    {
        if (pnt.Count == 2)
        {
            LinearGradientBrush liner =
                         new LinearGradientBrush(pnt[0], pnt[1],
                     Color.Transparent,
                         Color.Black);
            Pen pen = new Pen(liner);
            g.DrawLines(pen, pnt.ToArray());

            pnt.Clear();
        }
    }
    }

1 个答案:

答案 0 :(得分:0)

调用paint方法时,只调用一次DrawLines(Graphics g)方法。这意味着您只想在此方法中绘制所有行。但是, g.DrawLines(pen, sd);不在任何循环中。 因此,它在执行时只能绘制一行

我认为g.DrawLines(pen, sd);应该处于某种循环中,它不会反复'n'次(其中n是你想要绘制的行数)。