1

So I realise doing:

panel1.CreateGraphics()

is heavily looked down upon, but I'm making a paint app and I can't see any other way of doing it, simply because if I call panel1.Invalidate(); it obviously does not save the lines the user has drawn. So here's my code:

 private void pnlPaintPanel_MouseDown(object sender, MouseEventArgs e)
    {
        shouldPaint = true;
        prePoint = new Point(e.X, e.Y);
    }

    private void pnlPaintPanel_MouseUp(object sender, MouseEventArgs e)
    {
        shouldPaint = false;
    }

    private void pnlPaintPanel_MouseMove(object sender, MouseEventArgs e)
    {
        curPoint = new Point(e.X, e.Y);
        if (shouldPaint)
        {
            pnlPaintPanel.Invalidate();
        }
        prePoint = new Point(e.X, e.Y);
    }

    private void pnlPaintPanel_Paint(object sender, PaintEventArgs e)
    {
        using (Pen p = new Pen(chosenColor, penSize))
        {
            p.StartCap = LineCap.Round;
            p.EndCap = LineCap.Round;
            e.Graphics.DrawLine(p, prePoint, curPoint);
        }

    }

This obviously doesn't work because it just clears any paint the user puts down immediately. I'm sure there's a clever way of doing it; can anyone help?

Chai_Latte
  • 59
  • 4
  • [Here is an example](https://stackoverflow.com/questions/31988079/copying-free-hand-drawing-from-panel-in-visual-studio-2013/32112426?s=2|0.4146#32112426) - The trick is to have a List of data you need for drawing. Start with a List>! Sounds complicated? Not when you think about it: You want several (list1) curves (list2).. – TaW Jun 09 '17 at 22:11
  • So I tried this, you're right, it works, (I actually read your amazing post on it already, very informative learned a lot). My only problem is as the panel is invalidated it constantly flashes white (because it is being re-painted) , with bigger pens the lines have glitches at turning points and when pen size is changed ALL the lines change size. The flashing panel is the main problem though, know any way to fix this? – Chai_Latte Jun 09 '17 at 22:14
  • 1
    See [How do I double buffer a Panel in C#?](https://stackoverflow.com/a/818447/719186) – LarsTech Jun 09 '17 at 22:30
  • You need to Double-Buffer the Panel, either by reflection or by creating a subclass. In this case I suggest a subclass as it will allow you to add more behaviour to it.. [Here is an example](https://stackoverflow.com/questions/32019439/c-sharp-how-to-draw-a-rubber-band-selection-rectangle-on-panel-like-one-used-in/39179990#39179990) - `class DrawPanel : Panel { public DrawPanel() { DoubleBuffered = true; } })` – TaW Jun 09 '17 at 23:10
  • For the glitches in the lines do set suitable values for these Pen properties: LineJoin, MiterXyz, End/StartCaps! For Miter use ca. 1/2 of the Pen.Width. I usually prefer Round caps&joinis.. – TaW Jun 09 '17 at 23:13
  • Thanks a lot my app now works perfectly! – Chai_Latte Jun 10 '17 at 12:35

1 Answers1

1

There are two ways to do it.

  1. Instead of drawing to the panel directly have a Bitmap and use Graphics.FromImage( to get the graphics object, then just set the background of the panel to the bitmap.

  2. Have all the drawing be recorded as a series of steps then re-draw the steps every paint event.

Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
  • And for really complex drawing you can combine both and 'cache' the every 100 or 1000.. points owrth in a bitmap.. – TaW Jun 09 '17 at 23:13