如何在 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
问题
我有一个要在面板上绘制的点列表,我有一个方法来检查前一个点是否为空,如果不为空则应该从前一个点开始画一条新线到下一点。相反,当我单击按钮 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