0

And trying get working small paint application, that draws only lines with mouse event.

Could someone provide me with correct working example how to create undo functionality? I have picturebox1 with Events pictureBox1_MouseDown, pictureBox1_MouseMove, pictureBox1_MouseUp.

When I moving mouse and and clicking on picture box it is drawing lines as expected. But how to create undo functionality for example on undo button click?

     private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {

            lx = e.X;
            ly = e.Y;

            Graphics g = pictureBox1.CreateGraphics();
            g.DrawLine(new Pen(new SolidBrush(paintcolor), 3), new Point(x, y), new Point(lx, ly));


            this.Invalidate();

        }




   private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            x = e.X;
            y = e.Y;

        }




  private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {

        }

I create additionally

class Shape
{

    public string _font { get; set; }
    public string g { get; set; }
    public int x { get; set; }
    public int y { get; set; }
    public int lx { get; set; }
    public int ly { get; set; }
    public string paintcolor { get; set; }
    public string s { get; set; }


}

then added under public partial class Form1 : Form

private Stack<Shape> _shapes = new Stack<Shape>();

than add to pictureBox1_MouseUp

newShape._font = _font.ToString();
            newShape.g = g.ToString();
            newShape.x = x;
            newShape.y = y;
            newShape.lx = lx;
            newShape.ly = ly;
            newShape.paintcolor = paintcolor.ToString();




                _shapes.Push(newShape);


            this.Invalidate();

and for Undo button btnUndo

  private void btnUndo_Click(object sender, EventArgs e)
        {


            if (_shapes.Count > 0)
            {

                this.pictureBox1.Invalidate();
                _shapes.Pop();


            }
            else
            {
                MessageBox.Show("Nothing to remove.", "No Shapes",
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

        }

and put break-point on _shapes.Push(newShape);

that _shapes are filed with values

and when I push button btnUndo

I see that _shapes.Pop(); removing values LIFO, but of course my lines did not disappears. So I'm confused because I have feeling that I need create lines on pictureBox1 not from mouse movements, but from Stack.

Yanka
  • 21
  • 1
  • 5
  • 1
    Shouldn't you Invalidate after you Pop the shape? – Lithium Aug 10 '17 at 10:09
  • Yes, for **pictureBox1_MouseUp** _shapes.Push(newShape); //this.pictureBox1.Invalidate(); //this.pictureBox1.Invalidate(); this.Invalidate(); for **btnUndo_Click** tested if (_shapes.Count > 0) { // pictureBox1.Invalidate(); this.pictureBox1.Invalidate(); _shapes.Pop(); //this.pictureBox1.Invalidate(); } – Yanka Aug 10 '17 at 10:16
  • 1
    Winforms = winapi, so you have to follow its design. Move all drawing logic into `Paint` event, you already have some collection to hold figures to paint, in `Paint` event you just **repaint** all of them (with clearing background). To add figure: add it to collection, call `Invalidate` (this will execute `Paint` event, so you will see your figure). To delete: remove it from collection, call `Invalidate` (`Paint` will draw less figures - it will looks like it's *undone*). – Sinatr Aug 10 '17 at 10:17
  • Hi Sinatr, is behind your idea is something like this? http://www.c-sharpcorner.com/uploadfile/dbeniwal321/adding-a-paint-event-handler-to-a-form-and-controls-in-gdi/ – Yanka Aug 10 '17 at 10:26
  • Thank You for advice, problem is solved. – Yanka Aug 10 '17 at 13:25
  • Thank You for advice, problem is solved. I create on pictureBox1 one more event **Appearance -> Paint pictureBox1_Paint** and create and add in to ` private void pictureBox1_Paint(object sender, PaintEventArgs e) { foreach (Shape shp in _shapes) { e.Graphics.DrawLine(new Pen(new SolidBrush(paintcolor), 3), shp.x, shp.y, shp.lx, shp.ly); } }` And then Pop() works as expected. Thanks for advice :) – Yanka Aug 10 '17 at 13:30

0 Answers0