-1

I have my own class that extends of PictureBox. I have a problem when I draw a circle arround it. The problem was on the "base.OnPaint(e)" and it throws an ArgumentException. I put the code below and then the complete class.

The method that throws the exception:

private void Parent_Paint(object sender, PaintEventArgs e)
    {
        if (clickPerformed)
        {
            using (Graphics g = e.Graphics)
            {
                using (Pen pen = new Pen(Color.Black, 2))
                {
                    float locationX = this.Location.X + this.Size.Width / 2;
                    float locationY = this.Location.Y + this.Size.Height / 2;
                    float radius = (this.Size.Height + this.Size.Width) / 2;

                    float[] dashValues = { 5, 2, 15, 4 };
                    pen.DashPattern = dashValues;
                    DrawCircle(g, pen, locationX, locationY, radius); // draw circle 
                    clickPerformed = false; // process done so set it to false
                }
            }
        }
        base.OnPaint(e);
    }

The Unidad.cs class:

public class Unidad : PictureBox
{
    //Constructor
    public Unidad(string nombre, string tipo, int movimiento, int ha, int hp, int fuerza, int resistencia, int heridas, int iniciativa, int ataques, int liderazgo, int coste, string rutaImagen)
    {
        tipoUnidad = tipo;
        movimientoUnidad = movimiento;
        nombreUnidad = nombre;
        costeUnidad = coste;
        haUnidad = ha;
        hpUnidad = hp;
        fuerzaUnidad = fuerza;
        resistenciaUnidad = resistencia;
        iniciativaUnidad = iniciativa;
        ataquesUnidad = ataques;
        liderazgoUnidad = liderazgo;
        rutaImagenUnidad = rutaImagen;
    }

    //Propiedades
    public string nombreUnidad { get; set; }
    public string tipoUnidad { get; set; }
    public int movimientoUnidad { get; set; }
    public int costeUnidad { get; set; }
    public int haUnidad { get; set; }
    public int hpUnidad { get; set; }
    public int fuerzaUnidad { get; set; }
    public int resistenciaUnidad { get; set; }
    public int heridasUnidad { get; set; }
    public int iniciativaUnidad { get; set; }
    public int ataquesUnidad { get; set; }
    public int liderazgoUnidad { get; set; }
    public string rutaImagenUnidad { get; set; }

    //Método para dibujar unidad
    public void Colocar(Control control, Unidad unidad, Point p)
    {
        unidad.Location = p;
        control.Controls.Add(unidad);
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        if (this.Parent != null)
        {
            this.Parent.Paint += Parent_Paint; // picturebox's paint means it added to parent so we need to trigger parent's paint event
        }
        base.OnPaint(pe);

    }
    bool clickPerformed = false; // to catch control has mouse down
    private Point MouseDownLocation;
    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);
        clickPerformed = true; // set mouse down
        Control tempSender = this.Parent; // get sender
        tempSender.Invalidate(); // invalidate to trigger paint event
        MouseDownLocation = e.Location;

    }

    private void Parent_Paint(object sender, PaintEventArgs e)
    {
        if (clickPerformed)
        {
            using (Graphics g = e.Graphics)
            {
                using (Pen pen = new Pen(Color.Black, 2))
                {
                    float locationX = this.Location.X + this.Size.Width / 2;
                    float locationY = this.Location.Y + this.Size.Height / 2;
                    float radius = (this.Size.Height + this.Size.Width) / 2;

                    float[] dashValues = { 5, 2, 15, 4 };
                    pen.DashPattern = dashValues;
                    DrawCircle(g, pen, locationX, locationY, radius); // draw circle 
                    clickPerformed = false; // process done so set it to false
                }
            }
        }
        base.OnPaint(e);
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        this.Parent.Invalidate(); // mouse up circle should be erased, so invalidate again to trigger paint, but this time clickPerformed is false
                                  // so it won't draw circle again
        base.OnMouseDown(e);
    }
    public void DrawCircle(Graphics g, Pen pen, float centerX, float centerY, float radius)
    {
        g.DrawEllipse(pen, centerX - radius, centerY - radius, radius + radius, radius + radius);
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        base.OnMouseMove(e);
        if (clickPerformed)
        {
            Left = e.X + Left - MouseDownLocation.X;
            Top = e.Y + Top - MouseDownLocation.Y;
        }
    }


    //Método para dibujar la zona límite de movimiento de la unidad
    public void DibujarLimites()
    {
        using (Graphics g = CreateGraphics())
        {
            using (Pen pen = new Pen(Color.Red, 2))
            {
                float[] dashValues = { 5, 2, 15, 4 };
                pen.DashPattern = dashValues;
                DrawCircle(g, pen, 0, 0, 20);
            }
        }
    }
}

When I remove the "base.OnPaint(e)" line, it gives me an "System.ArgumentException' in System.Drawing.dll" at Program.cs, on line:"Application.Run(new Form1());"

Can anyone help me? Thanks!

Imrik
  • 674
  • 2
  • 14
  • 32
  • 2
    Why do you call `base.OnPaint()` _after_ you painted yourself? This will overpaint your drawings again. And I guess the exception occures because you `Dispose` the `Graphics` instance in the event arguments before you call `base.OnPaint()`. Remove the `using` statement that disposes the `Grahics` instance. – René Vogt Mar 07 '17 at 08:40
  • `base.OnPaint()` is usually used in `override OnPaint`. – Lei Yang Mar 07 '17 at 08:44
  • `using (Graphics g = e.Graphics)` you didn't create it so you shan't dispose of it! – TaW Mar 07 '17 at 08:44
  • it fix the problem! Thanks all of you, I only have to remove the using statement and it works. – Imrik Mar 07 '17 at 08:48
  • But now I have another problem, when I click on one of my pictureBoxes it draws the circle correctly, but also it draws one more pictureBox on the top left corner of the form. Any idea of why is doing that? Before this I changes I can click on the pictureBoxes and it shows me a MessageBox, but it doesn't draw anything "extra". – Imrik Mar 07 '17 at 08:49

1 Answers1

0

I solve it with the comments help. I only have to remove the using statement on Graphics.

Thanks! :)

Imrik
  • 674
  • 2
  • 14
  • 32
  • may be you should include the using statements in your question post. so that the answer/solution becomes a little more obvious. – Mong Zhu Mar 07 '17 at 09:47