#c# #line #panel #point
Вопрос:
Проблема
У меня есть список точек, которые я хочу нарисовать на панели, у меня есть метод проверки, является ли предыдущая точка нулевой, если она не равна нулю, то предполагается провести новую линию от предыдущей точки к следующей точке. Вместо этого , когда я нажимаю на кнопку 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();
}
}
Выход
Комментарии:
1. Могут быть и другие проблемы, но мне кажется, что последние
DrawLine()
должны быть за пределамиforeach
.2. @500-InternalServerError, Спасибо, что попробовали это немного
3. Графика g = панель 1. CreateGraphics(); Обычно это действительно плохая идея, так как результирующая графика не будет постоянной. Вместо этого нарисуйте событие Paint и используйте там объект e.Graphics. Вы также можете использовать непостоянные строки, используя g.DrawLines() (множественное число!), Но любая последовательность минимизации/максимизации очистит их..
4. Ага. Вам нужно следовать правилам GDI grpahics: Рисуйте только в/из события Paint с помощью параметра e.Graphics. Вам нужно будет где-то сохранить все необходимые параметры; также используйте Invalidate для запуска Paint при необходимости, т. Е. Всякий раз, когда параметры меняются!
5.
Point
это структура, и ее никогда не будетnull
. Проверьте,Point.Empty
может быть, вместо этого.
Ответ №1:
Этот код
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
Комментарии:
1. Это гениально, это сработало, Спасибо