1

Im doing a small assignment for a class where you have to create a paint application that draws circles, rectangles, lines with colors. I've done most of the work but I cant seem to get it to work properly. Right now it draws rectangles as it should (with mouse) but as soon as I want to draw another one it deletes the original and does a new one (it shouldnt do this). It does this because of the system Control.Refresh(); method Im using - but I have to use it in order to draw proper rectangles, otherwise it draws rectangles like this:

Example of retangles (wrong)

Is there a way to use the Refresh() method so it draws the rectangles correctly, but also doesnt refresh the form and delete the existing stuff drawn?

The full code I have now:

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 MD4
{
    public partial class Form1 : Form
    {
        Graphics g;
        int x = -1;
        int y = -1;
        bool moving = false;
        Pen pen;
        bool line = false, rectangle = false, ellipse = false, eraser = false, penDraw = true;

        Rectangle rect;
        Point LocationXY; //Rectangle/Ellipse start location
        Point LocationX1Y1; //Rectangle/Ellipse end location

        public Form1()
        {
            InitializeComponent();
            g = panel1.CreateGraphics();
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            pen = new Pen(Color.Black, 5);
            pen.StartCap = pen.EndCap = System.Drawing.Drawing2D.LineCap.Round;
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            PictureBox p = (PictureBox)sender;
            pen.Color = p.BackColor;

        }

        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            moving = true;
            x = e.X; //Starting x and Y
            y = e.Y;
            panel1.Cursor = Cursors.Cross;

            LocationXY = e.Location;


        }

        private void panel1_MouseUp(object sender, MouseEventArgs e)
        {
            if(moving == true)
            {
                LocationX1Y1 = e.Location;
            }

            moving = false;
            x = -1;
            y = -1;
            panel1.Cursor = Cursors.Default;
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            if(moving && x!= -1 && y != -1)
            {

                LocationX1Y1 = e.Location;

                //Refresh();

                if (eraser)
                {
                    pen.Color = Color.White;
                    pen.Width = 50;
                    g.DrawLine(pen, new Point(x, y), e.Location);
                    x = e.X;
                    y = e.Y;
                }

                if (rectangle)
                {
                    if (rect != null)
                    {
                        Refresh(); //This is the problem I think. It refreshes as soon as you start drawing a new rectangle. If I put this in the MouseMove event, the 'Pen' funciton doesnt work so it has to go here..
                        pen.Width = 5;
                        g.DrawRectangle(pen, GetRect());
                    }
                }

                if (ellipse)
                {
                    Refresh();
                    pen.Width = 5;
                    g.DrawEllipse(pen, GetRect());
                }

                if (penDraw)
                {
                    pen.Width = 5;
                    g.DrawLine(pen, new Point(x, y), e.Location);
                    x = e.X;
                    y = e.Y;
                }

                if (line)
                {
                    //NOT DONE YET
                }
            }
        }


        private Rectangle GetRect()
        {
            rect = new Rectangle();

            rect.X = Math.Min(LocationXY.X, LocationX1Y1.X);

            rect.Y = Math.Min(LocationXY.Y, LocationX1Y1.Y);

            rect.Width = Math.Abs(LocationXY.X - LocationX1Y1.X);

            rect.Height = Math.Abs(LocationXY.Y - LocationX1Y1.Y);

            return rect;
        }

        private void drawPen_Click(object sender, EventArgs e)
        {
            line = false;
            rectangle = false;
            ellipse = false;
            eraser = false;
            penDraw = true;
        }

        private void lineButton_Click(object sender, EventArgs e)
        {
            line = true;
            rectangle = false;
            ellipse = false;
            eraser = false;
            penDraw = false;
        }

        private void rectangleButton_Click(object sender, EventArgs e)
        {
            rectangle = true;
            line = false;
            ellipse = false;
            eraser = false;
            penDraw = false;
        }

        private void ellipseButton_Click(object sender, EventArgs e)
        {
            ellipse = true;
            line = false;
            rectangle = false;
            eraser = false;
            penDraw = false;
        }

        private void eraserButton_Click(object sender, EventArgs e)
        {
            eraser = true;
            rectangle = false;
            line = false;
            ellipse = false;
            penDraw = false;
        }
    }
}
H H
  • 263,252
  • 30
  • 330
  • 514
B. Baxter
  • 133
  • 1
  • 10
  • Where `Refresh` function. – CorrM Dec 24 '19 at 10:09
  • Sorry, I meant the system Control.Refresh(); method. – B. Baxter Dec 24 '19 at 10:15
  • why u want to refresh .? just draw and when u want to clear, refresh ! like here https://www.c-sharpcorner.com/uploadfile/mahesh/drawing-ellipses-and-circles-in-gdi/ – CorrM Dec 24 '19 at 10:22
  • 1
    If you want to refresh, you have to save the drawn objects somehow (i suggest using a List) and draw them again. – Isitar Dec 24 '19 at 10:23
  • 1
    Think about how Paint does Undo and Redo. Windows doesn't store your pixels, you will have to implement the OnPaint event on the main Control and be able to reproduce your content on demand. – H H Dec 24 '19 at 10:24
  • And you should avoid CreateGraphics() . – H H Dec 24 '19 at 10:27
  • You cannot use CreateGraphics() and you have to store the shapes you're ve drawn. See the example [here](https://stackoverflow.com/a/53708936/7444103), doing this exactly. – Jimi Dec 25 '19 at 12:15

0 Answers0