0

I am trying to set the starting point when the LMB is down and draw a line from the starting point to the current mouse position when the LMB is up, much like how MSPaint does it.

My problem is that I can't seem to get the line to appear on the picturebox when LMB is up. Can someone enlighten me please?

Edit:Sorry guys I realised the problem was elsewhere, but I learned a bunch of stuff in the process, thanks for all the input.

public partial class FormPaint : Form
{    
    Point? startPoint = Point.Empty;
    Point? endPoint = Point.Empty;
    bool isMouseDown = new Boolean();

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        if (Control.MouseButtons == MouseButtons.Left)
        {
            startPoint = e.Location;
            isMouseDown = true;
        }
    }

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {

         brush = new SolidBrush(color);
         using (Graphics g = Graphics.FromImage(pictureBox1.Image))
         {
              g.DrawLine(new Pen(brush), startPoint.Value, endPoint.Value);
              pictureBox1.Invalidate();

         }

        isMouseDown = false;

    }
    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
      endPoint = e.Location;
    }
     private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
         using (brush = new SolidBrush(color))
         {
               e.Graphics.DrawLine(new Pen(brush, 5), startPoint.Value, endPoint.Value);
         }
    }
}
  • 1
    Just curious... why are your `Point`s nullable? Also, `bool isMouseDown = false;` is probably more clear. – Ed S. Jun 04 '15 at 06:57
  • 1
    You don't check whether mouse button is pressed in `pictureBox1_MouseMove` and assign value to `endPoint` in any case. – Alex F Jun 04 '15 at 06:58
  • You need to invalidate during MouseMove as well. – TaW Jun 04 '15 at 07:12
  • @EdS. I was browsing through some forums to find similar problems and saw a post using it, so I figured it might somehow do something – Johann Sutherland Jun 04 '15 at 07:37
  • It's a good idea to understand every line of code in your program. Here is an article which seems relevant: http://en.wikipedia.org/wiki/Cargo_cult_programming – Ed S. Jun 04 '15 at 17:27

2 Answers2

0

When you call Invalidate it forces the picture box to repaint. The problem is though that it discards everything you painted before. Then it calls the Paint on the picture box.

I would suggest to save the drawing data into a list and perform the painting inside the Paint event of the picture box using that saved data.

Also read How do I draw a circle and line in the picturebox?

Community
  • 1
  • 1
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
0

Complete sample with line draw preview, enjoy.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WinForm
{
    public partial class frmMain : Form
    {
        /// <summary>
        /// form constructor
        /// </summary>
        public frmMain()
        {
            InitializeComponent();
        }

        private PictureBox imgCanvas;
        private bool isMouseDown;
        private Point startPoint;
        private Point currentPoint;

        /// <summary>
        /// form load
        /// </summary>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            imgCanvas = new PictureBox
            {
                Location = new Point(8, 8),
                Size = new Size(this.ClientSize.Width - 16, this.ClientSize.Height - 16),
                Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right | AnchorStyles.Bottom,
                BorderStyle = BorderStyle.Fixed3D,
            };
            imgCanvas.MouseDown += imgCanvas_MouseDown;
            imgCanvas.MouseUp += imgCanvas_MouseUp;
            imgCanvas.MouseMove += imgCanvas_MouseMove;
            imgCanvas.Paint += imgCanvas_Paint;
            this.Controls.Add(imgCanvas);
        }

        void imgCanvas_Paint(object sender, PaintEventArgs e)
        {
            if (isMouseDown)
            {
                e.Graphics.DrawLine(Pens.Red, startPoint, currentPoint);
            }
        }

        void imgCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (isMouseDown)
            {
                currentPoint = e.Location;
                (sender as PictureBox).Refresh();
            }
        }

        void imgCanvas_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                isMouseDown = true;
                startPoint = e.Location;
            }
        }

        void imgCanvas_MouseUp(object sender, MouseEventArgs e)
        {
            if (isMouseDown)
            {
                if (e.Button == MouseButtons.Left)
                {
                    isMouseDown = false;

                    PictureBox pb = sender as PictureBox;

                    // create image
                    if (pb.Image == null)
                    {
                        pb.Image = new Bitmap(pb.ClientSize.Width, pb.ClientSize.Height);
                    }

                    // draw
                    using (Graphics g = Graphics.FromImage(pb.Image))
                    {
                        g.DrawLine(Pens.Green, startPoint, e.Location);
                        pb.Refresh();
                    }
                }
            }
        }
    }
}

Result:

Screenshot

General-Doomer
  • 2,681
  • 13
  • 13