Search code examples
c#winformsdrawingshapes

Existing shapes not visible while creating new shape in Window Form application


I created a Window form and within this project I have the following code:

public partial class Form1 : Form
{

    Rectangle _rectangle;
    List<Rectangle> _rectangles = new();
    Point LocationXY;
    Point LocationXYEnd;

    bool MouseIsDown = false;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void Form1_MouseDown(object sender, MouseEventArgs e)
    {
        MouseIsDown = true;
        LocationXY = e.Location;
    }

    private void Form1_MouseMove(object sender, MouseEventArgs e)
    {
        if (MouseIsDown)
        {
            LocationXYEnd = e.Location;
            Refresh();
        }
    }

    private void Form1_MouseUp(object sender, MouseEventArgs e)
    {
        if (MouseIsDown)
        {

            LocationXYEnd = e.Location;
            MouseIsDown = false;

            _rectangles.Add(GetRectangle());
            
            foreach (var rect in _rectangles)
            {
                System.Drawing.Graphics formGraphics;
                formGraphics = this.CreateGraphics();
                formGraphics.DrawRectangle(new Pen(Color.Black), rect);
                formGraphics.Dispose();
            }

        }
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        if (_rectangles != null)
        {
            e.Graphics.DrawRectangle(Pens.Black, GetRectangle());
        }
    }

    private Rectangle GetRectangle()
    {
        _rectangle = new Rectangle();
        _rectangle.X = Math.Min(LocationXY.X, LocationXYEnd.X);
        _rectangle.Y = Math.Min(LocationXY.Y, LocationXYEnd.Y);
        _rectangle.Width = Math.Abs(LocationXY.X - LocationXYEnd.X);
        _rectangle.Height = Math.Abs(LocationXY.Y - LocationXYEnd.Y);
        return _rectangle;
    }


}

Whenever I am drawing a new shape, the existing shapes are not visible. When I release my mouse the new shape is added to the list and all other shapes are visible again.

I've tried to fix this, but without success. Anyone who can help?


Solution

  • Your code looks "mostly right" but what I notice is that you handle the Paint event by drawing just the new rectangle. In fact, you've been handed a blank canvas with the e.Graphics so go ahead and repaint the entire collection of rectangles.

    new and existing rectangles

    public partial class MainForm : Form
    {
        List<Rectangle> _rectangles = new();
        Rectangle _rectInProgress;
        public MainForm()
        {
            InitializeComponent();
            DoubleBuffered = true;
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            if (_rectangles.Any())
            {
                e.Graphics.DrawRectangles(Pens.Blue, _rectangles.ToArray());
            }
            if (MouseButtons == MouseButtons.Left)
            {
                e.Graphics.DrawRectangle(Pens.Red, _rectInProgress);
            }
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            _rectInProgress = new Rectangle(e.Location, new Size());
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if(MouseButtons == MouseButtons.Left)
            {
                _rectInProgress.Width = e.Location.X - _rectInProgress.X;
                _rectInProgress.Height = e.Location.Y - _rectInProgress.Y;
                Invalidate();
            }
        }
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            _rectangles.Add(_rectInProgress);
            Invalidate();
        }
    }