如何在 C# 中使用面板、图形和点绘制点到点的线

How to draw a line from point to point in C# with Panel, Graphics and Points

问题

我有一个要在面板上绘制的点列表,我有一个方法来检查前一个点是否为空,如果不为空则应该从前一个点开始画一条新线到下一点。相反,当我单击按钮 initialize_shape 时,我得到的输出是一条连接两点的单线,显示其余点,但它们之间不存在任何线。

预期

我希望代码在每个点之间画一条线,这样它就形成了某种图案,每个点都通过一条线连接到下一个点,而不仅仅是一条线。

代码

 public partial class Form1 : Form
    {
 //declare the lists that will hold the points
        List<Point> Shape1 = new List<Point>();
//this method belongs to a button object that draws the shape
 private void button1_Click(object sender, EventArgs e)
        {
            Shape1.Clear();
            Shape2.Clear();
            Point p1a = new Point(20, 30);
            Point p2a = new Point(120,50);
            Point p3a = new Point(160,80);
            Point p4a = new Point(180, 300);
            Point p5a = new Point(100,220);
            Point p6a = new Point(50, 280);
            Point p7a = new Point(20, 140);
            //Hold the Points in an array
            Point[] mypoints = new Point[] {p1a,p2a,p3a,p4a,p5a,p6a,p7a};
            //add the points to the List with one call
            Shape1.AddRange(mypoints);
            //the pens are added here
            Pen pBlue = new Pen(Brushes.Blue, 1);
            Pen pRED = new Pen(Brushes.Red, 1);
            //The panel object used below is a control that was added to the form
            Graphics g = panel1.CreateGraphics();
            DisplayShape(Shape1, pBlue, g);
           }
       //This method is supposed to draw lines between the points on the 
       //Panel
         void DisplayShape(List<Point> Shp,Pen pen, Graphics G)
        {
            Point? prevPoint = null;//nullable
            foreach(Point pt in Shp)
            {
                G.DrawEllipse(pen, new Rectangle(pt.X - 2, pt.Y - 2, 4, 4));
                //something in this logic is not right
                if (prevPoint != null)
                {
                    G.DrawLine(pen, (Point)prevPoint, pt);
                    prevPoint = pt;
                }
                G.DrawLine(pen, Shp[0], Shp[Shp.Count - 1]);
            }

        }
  //this method intializes the form
  public Form1()
        {
            InitializeComponent();   
        }
}

输出

这个代码

if (prevPoint != null)
{
      G.DrawLine(pen, (Point)prevPoint, pt);
      prevPoint = pt;
}

永远不会 运行,因为 prevPoint 仅在 if 语句中设置。应该是

if (prevPoint != null)
{
      G.DrawLine(pen, (Point)prevPoint, pt);
}
prevPoint = pt;

或跳过初始点

if(Shp.Count < 2) return;
var prevPoint = Shp[0];
foreach(Point pt in Shp.Skip(1)){
    G.DrawLine(pen, prevPoint, pt);
}

另请注意:

  • G.DrawLine(pen, Shp[0], Shp[Shp.Count - 1]); 总是绘制相同的东西,所以不需要在循环内
  • 在按钮事件处理程序中绘制可能不是正确的方法,因为重绘控件时所有内容都将被清除。我建议将事件处理程序附加到 paint 事件。或者创建面板的子类并覆盖 OnPaint