Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Image is duplicated when the window is maximized

Tags:

c#

winforms

I am designing a HangMan game to learn how to use C# with DevExpress. My problem is that I am drawing the post with size relative to the panel size I am drawing it into, so that its size is recalculated if the window is resized. My code looks like this:

namespace HangMan
{
  public partial class HangMan : Form
  {
    public HangMan()
    {
        InitializeComponent();
        this.Paint += new System.Windows.Forms.PaintEventHandler(HangMan_Paint);
    }

    void drawHangPost()
    {

        //Use panel size percentages to draw the post
        double dWidth = pnlHang.Width; double dHeight = pnlHang.Height;

        int x1 = (int)Math.Round(0.8 * dWidth); int x2 = (int)Math.Round(0.45 * dWidth);
        int y1 = (int)Math.Round(dHeight); int y2 = (int)Math.Round(0.23 * dHeight);
        int xInit = x1; int xFinal = x1 - x2;
        int yInit = y1; int yMiddle = 10; int yFinal = y2;

        //Paint Post
        Graphics g = pnlHang.CreateGraphics();
        Pen p = new Pen(Color.Brown, 10);

        g.DrawLine(p, new Point(xInit, yInit), new Point(xInit, yMiddle));
        g.DrawLine(p, new Point(xInit, yMiddle), new Point(xFinal, yMiddle));
        g.DrawLine(p, new Point(xFinal, yMiddle), new Point(xFinal, yFinal));    
    }

    private void HangMan_Paint(object sender, EventArgs e)
    {
        drawHangPost();
    }        
  }
}

This works perfectly for me, and the post drawing is resized. However, when I resize the window manually, a new post is drawn in each step, so many of them appear. If I maximize the window, two posts of two different sizes appear.

Yet, when I minimize the window and open it again, just the proper drawing stays. Is there any way to eraise the previous drawings when a new one is drawn?

Should I include some kind of eraising command write after InitializeComponent() ?

like image 454
Slash Avatar asked Oct 19 '22 16:10

Slash


1 Answers

So a major part of your problem is you're responding to the Form's paint event and then painting to a control, which may or may not have been invalidated.

Instead you should subscribe to the panel's paint event and do your painting there with the Graphics object that gets passed into event arguments. Also you will want to handle the panel's resize event to invalidate it. I'm assuming you're using either anchors or docking to automatically resize the panel when the form is resized. If not you need to change it so that the panel is resized when the form is.

    public Form1()
    {
        InitializeComponent();

        pnlHang.Paint += PnlHangPaint;
        pnlHang.Resize += (sender, args) => pnlHang.Invalidate();
    }

    private void pnlHang_Paint(object sender, PaintEventArgs paintEventArgs)
    {
        drawHangPost(paintEventArgs.Graphics);
    }

    void drawHangPost(Graphics g)
    {
        //Use panel size percentages to draw the post
        double dWidth = pnlHang.Width;
        double dHeight = pnlHang.Height;

        int x1 = (int)Math.Round(0.8 * dWidth);
        int x2 = (int)Math.Round(0.45 * dWidth);
        int y1 = (int)Math.Round(dHeight);
        int y2 = (int)Math.Round(0.23 * dHeight);
        int xInit = x1;
        int xFinal = x1 - x2;
        int yInit = y1;
        int yMiddle = 10;
        int yFinal = y2;

        //Paint Post
        using (Pen p = new Pen(Color.Brown, 10))
        {
            g.DrawLine(p, new Point(xInit, yInit), new Point(xInit, yMiddle));
            g.DrawLine(p, new Point(xInit, yMiddle), new Point(xFinal, yMiddle));
            g.DrawLine(p, new Point(xFinal, yMiddle), new Point(xFinal, yFinal));
        }
    }

Also, any time you create a GDI resource like a pen or brush, make sure to dispose them! A C# using block accomplishes that nicely for you.

like image 69
Erik Avatar answered Oct 21 '22 09:10

Erik