Drawing a line from a dot to dot (Point to Point) on Form MouseDown
I've been working days on a program that draws a grid of dots, and I had to start all over again several times because of a bad approach / to complicated. I've come to a point now where I have to draw a line from a clicked dot (point) to a second clicked dot (point) on the form. Seriously I've been spending hours even days of my time searching for the right approach. As for now I only managed to get a line drawn from a point on the form to another point on the form on random clicks... Could someone please help get the code done, its just frustrating me how I don't have any progress after all attempts of drawing a grid of dots.. So what I want to do is "draw a line from a clicked dot (point) to a second clicked dot (point) on the form".
See below of my code:
Form1.cs:
public partial class Form1 : Form
{
private GridDrawing drawing;
private Point point1;
private Point point2;
List<Point> p1List = new List<Point>(); //Temp
List<Point> p2List = new List<Point>(); //Temp
//True if point1 must be updated
//False if point2 must be updated
private bool firstPoint = true;
private int sizeOfDot;
private int rows;
private int columns;
public Form1()
{
InitializeComponent();
sizeOfDot = 10; //The size of the dot
rows = 6; //The amount of rows for the matrix
columns = 8; //The amount of columns for the matrix
}
private void Form_Paint(object sender, PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.White, ClientRectangle); //Fill the form in white
drawing = new GridDrawing(this, rows, columns); //Control, Rows, Columns
foreach (var piece in drawing.Pieces) //Draws all the dots
{
e.Graphics.FillEllipse(Brushes.Black, (piece.Dot.X - sizeOfDot / 2),
(piece.Dot.Y - sizeOfDot / 2), sizeOfDot, sizeOfDot); //Draws the dot
}
using (var pen = new Pen(Color.Black, 2))
{
for (int i = 0; i < p1List.Count; i++)
{
e.Graphics.DrawLine(pen, p1List[i], p2List[i]);
}
}
}
private void startToolStripMenuItem_Click(object sender, EventArgs e)
{}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
if (firstPoint) //Update point1 or point2
{
//Point 1
point1.X = e.X;
point1.Y = e.Y;
}
else
{
//Point 2
point2.X = e.X;
point2.Y = e.Y;
p1List.Add(point1);
p2List.Add(point2);
}
firstPoint = !firstPoint; //Change the bool value
Invalidate(); //Redraw
}
private void Form1_SizeChanged(object sender, EventArgs e)
{
Invalidate();
}
}
GridDrawing.cs:
public class GridDrawing
{
private int columns;
private int rows;
private List<GridPiece> pieces;
private Point dot;
//private Point point1; //point1 to start drawing line from
//private Point point2; //point2 to end drawing line from
/// <summary>
/// Constructs a grid
/// </summary>
/// <param name="ctrl"></param>
/// <param name="rows"></param>
/// <param name="columns"></param>
/// <param name="sizeOfDot"></param>
public GridDrawing(Control ctrl, int rows, int column开发者_StackOverflow中文版s)
{
this.rows = rows; // The amount of rows in the matrix.
this.columns = columns; // The amount of columns in the matrix.
this.pieces = new List<GridPiece>(); // Initializes the List GridPieces
int xOffset = (int)ctrl.ClientRectangle.Width / (columns + 1); // FP offset for X
int yOffset = (int)ctrl.ClientRectangle.Height / (rows + 1); // FP offset for Y
//Generate the dots
for (int i = 0; i < rows; i++) //Matrix with 6 rows
{
for (int j = 0; j < columns; j++) //Matrix with 8 columns
{
dot = new Point((j + 1) * xOffset, (i + 1) * yOffset); // Center of the dot
GridPiece p = new GridPiece(dot); // Creates a piece
pieces.Add(p); // Puts the piece that has to be drawn in the List<GridPiece>pieces
}
}
}
public List<GridPiece> Pieces //Property List<GridPiece>pieces
{
get { return this.pieces; }
}
public Point Dot //Property Point dot
{
get { return this.dot; }
}
}
GridPiece.cs:
public class GridPiece
{
private Point dot;
/// <summary>
/// Constructor of GriedPiece
/// </summary>
/// <param name="bmpPic"></param>
/// <param name="position"></param>
public GridPiece(Point dot)
{
this.dot = dot;
}
public Point Dot
{
get { return dot; }
}
}
Here's an example how I'm trying to make it look like
Could someone please help me?
Here is how to do this. add following code
public class Line
{
public float X1 { get; set; }
public float X2 { get; set; }
public float Y1 { get; set; }
public float Y2 { get; set; }
}
public sealed class Grid : Panel
{
readonly DotDrawing drawing = new DotDrawing();
private List<Line> Markers { get; set; }
public Grid()
{
this.DoubleBuffered = true;
Markers = new List<Line>();
}
protected override void OnPaint(PaintEventArgs e)
{
foreach (Line line in Markers)
{
using (Pen pen = new Pen(Brushes.Black))
{
pen.Width = 2;
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.DrawLine(pen, line.X1, line.Y1, line.X2, line.Y2);
}
}drawing.Render(e.Graphics);
base.OnPaint(e);
}
private Dot lastDot;
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
var x = this.drawing.GetDotFromPoint(e.Location);
if (x != null)
{
lastDot = x;
}
else
{
lastDot = null;
}
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
var x = this.drawing.GetDotFromPoint(e.Location);
if (x != null)
{
Line line = new Line();
line.X1 = lastDot.Center.X;
line.Y1 = lastDot.Center.Y;
line.X2 = x.Center.X;
line.Y2 = x.Center.Y;
this.Markers.Add(line);
Invalidate();
}
}
}
public class Dot
{
public PointF Location { get; set; }
public int Radius { get; set; }
public PointF Center
{
get
{
return new PointF(this.Bounds.Left + (float)this.Radius,
this.Bounds.Top + (float)this.Radius);
}
}
public RectangleF Bounds
{
get
{
return new RectangleF(Location, new SizeF(2 * Radius, 2 * Radius));
}
}
public Dot()
{
Radius = 5;
}
}
public class DotDrawing
{
private List<Dot> Dots { get; set; }
public int RowCount { get; set; }
public int ColumnCount { get; set; }
public int ColumnSpacing { get; set; }
public int RowSpacing { get; set; }
public int DotRadius { get; set; }
public DotDrawing()
{
Dots = new List<Dot>();
DotRadius = 10;
ColumnCount = 15;
RowCount = 25;
this.RowSpacing = 30;
this.ColumnSpacing = 30;
}
public void Render(Graphics g)
{
this.Dots.Clear();
float x = 0;
float y = 0;
for (int i = 0; i < RowCount; i++)
{
for (int j = 0; j < ColumnCount; j++)
{
{
Dot dot = new Dot();
dot.Location = new PointF(x, y);
using (SolidBrush brush = new SolidBrush(ColorTranslator.FromHtml("#009aff")))
{
g.FillEllipse(brush, dot.Location.X, dot.Location.Y, DotRadius, DotRadius);
}
x += (DotRadius + ColumnSpacing);
Dots.Add(dot);
}
}
x = 0;
y += (DotRadius + this.RowSpacing);
}
}
public Dot GetDotFromPoint(PointF point)
{
for (int i = 0; i < this.Dots.Count; i++)
{
RectangleF rect = this.Dots[i].Bounds;
rect.Inflate(new SizeF(3, 3));
Region region = new Region(rect);
if (region.IsVisible(point))
{
return this.Dots[i];
}
}
return null;
}
}
Drag the Grid from the tool box. Mouse Click on any of the dots without releasing it point to another grid you'll see the effect.
精彩评论