Draw an Arrow on a Picturebox in C#

13,623

Solution 1

Here is some basic code to draw lines in a picturebox from mouse down to current location.
You just need to draw some more lines or a triangle for the arrow head.

public partial class Form1 : Form
{
    private bool isMoving = false;
    private Point mouseDownPosition = Point.Empty;
    private Point mouseMovePosition = Point.Empty;
    private List<Tuple<Point, Point>> lines = new List<Tuple<Point, Point>>();
    public Form1()
    {
        InitializeComponent();

        // 
        // pictureBox1
        // 
        this.pictureBox1.Location = new System.Drawing.Point(0, 0);
        this.pictureBox1.Name = "pictureBox1";
        this.pictureBox1.Size = new System.Drawing.Size(231, 235);
        this.pictureBox1.TabIndex = 0;
        this.pictureBox1.TabStop = false;
        this.pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
        this.pictureBox1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseDown);
        this.pictureBox1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseMove);
        this.pictureBox1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseUp);
        this.Controls.Add(this.pictureBox1);
    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        var g = e.Graphics;
        if (isMoving)
        {
            g.Clear(pictureBox1.BackColor);
            g.DrawLine(Pens.Black, mouseDownPosition, mouseMovePosition);
            foreach (var line in lines)
            {
                g.DrawLine(Pens.Black, line.Item1, line.Item2);
            }
        }
    }

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        isMoving = true;
        mouseDownPosition = e.Location;
    }

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        if (isMoving)
        {
            mouseMovePosition = e.Location;
            pictureBox1.Invalidate();
        }
    }

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        if (isMoving)
        {
            lines.Add(Tuple.Create(mouseDownPosition, mouseMovePosition));
        }
        isMoving = false;
    }
}

Solution 2

It's easy to draw arrows in the same way that you worked out how to draw lines on a PictureBox in a previous question.

All you have to do is specify a StartCap or EndCap for the Pen object you are already using to draw lines. Intuitively, the StartCap property allows you to specify a cap style that is used at the beginning of any lines you draw with the Pen object, while the EndCap property allows you to specify a cap style for the end of the lines.

Several different LineCap styles are available, including:

Flat          Specifies a flat line cap.
Square        Specifies a square line cap.
Round         Specifies a round line cap.
Triangle      Specifies a triangular line cap.
NoAnchor      Specifies no anchor.
SquareAnchor  Specifies a square anchor line cap.
RoundAnchor   Specifies a round anchor cap.
DiamondAnchor Specifies a diamond anchor cap.
ArrowAnchor   Specifies an arrow-shaped anchor cap.
Custom        Specifies a custom line cap.
AnchorMask    Specifies a mask used to check whether a line cap is an anchor cap.

You will probably find the ArrowAnchor style most useful in this case: just specify an ArrowAnchor as the LineCap style for either the start or end of the line (depending on the direction in which you want the arrow to point).

The following code will draw a green, right-facing arrow with a line thickness of 4:

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
 //Create a new pen to draw the arrow with
 using (Pen p = new Pen(Brushes.Green, 4f))
 {
  //Specify the EndCap, because we're drawing a right-facing arrow
  p.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;

  //Draw the arrow
  e.Graphics.DrawLine(p, 0, 0, 30, 45);
 }
}

Solution 3

with reference to Albin Sunnanbo answer that was great stuff

If you want to draw arrow just replace

 g.DrawLine(Pens.Black, mouseDownPosition, mouseMovePosition); 

to

Pen p = new Pen(Color.Black,3);
p.StartCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
g.DrawLine(p, mouseDownPosition, mouseMovePosition);
p.Dispose();
Share:
13,623
Chris Bacon
Author by

Chris Bacon

Updated on June 04, 2022

Comments

  • Chris Bacon
    Chris Bacon almost 2 years

    I want to be able to draw a straight arrow from one mouse click location to another, as if you were doing it in PowerPoint. It needs to be able to draw on a PictureBox as well.