Graphics.Clear en un Windows Form Control también borra el control en sí mismo. ¿Cómo evitar esto?

Intento dibujar un rectángulo de selección personalizado en un Picturebox, usando el método a continuación:

    void _drag_UpdateView(bool clearOnly, MouseEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("UpdateView");
        using (Graphics g = this.i_rendered.CreateGraphics())
        {
            g.Clear(Color.Transparent);
            if (clearOnly)
                return;
            int px = (_drag_start.X > e.Location.X)?e.Location.X:_drag_start.X;
            int py = (_drag_start.Y > e.Location.Y)?e.Location.Y:_drag_start.Y;
            if (px < 0)
                px = 0;
            if (py < 0)
                py = 0;
            int wx = Math.Abs(e.Location.X-_drag_start.X);
            int wy = Math.Abs(e.Location.Y-_drag_start.Y);
            g.DrawRectangle(Pens.LightBlue, px, py, wx, wy);
        }
    }

Siempre que llamo:

g.Clear(Color.Transparent);

toda la caja de imágenes se vuelve negra. Sin embargo, el rectángulo se dibuja sobre él. Si no llamo a ese método, los rectángulos se apilan sobre sí mismos, por supuesto. Quiero eliminar el rectángulo anterior y crear uno nuevo como este.

¿Alguien puede describir lo que está mal?

preguntado el 22 de mayo de 12 a las 15:05

Cambie su lógica de pintura, haga el dibujo en OnPaint/OnPaintBackground para que no necesite llamar a Graphics.Clear -

+1 Adriano, deberías hacer de ese comentario una respuesta. Rara vez necesita usar "CreateGraphics" para dibujar controles. -

@Adriano: lo intenté ahora, pero ahora todo el control se volvió blanco. aquí - Yo tampoco veo el rectángulo. -

@Tgys no necesita usar CreateGraphics si está dentro del controlador de eventos Paint, simplemente use e.Graphics. -

@AndersForsgren Soy perezoso y es una respuesta corta sin ningún código o explicación, ¡no es suficiente para una respuesta! -

1 Respuestas

No pinte su control dentro de ningún otro método que no sea OnPaintBackground or OnPaint.

En realidad, es posible que lo necesite por razones de rendimiento (no actualizará el control completo, solo cambiará algo sobre la marcha), pero hará que su código sea mucho más complicado y siempre tendrá que hacer el mismo trabajo dentro del Paint evento también (porque puede llamarse por muchas otras razones, por lo que la salida debería ser la misma).

Dentro de la Paint ni siquiera necesitas usar CreateGraphics, el contexto gráfico está dentro del PaintEventArgs objeto así que cambia tu código a:

void DoPainting(object sender, PaintEventArgs e)
{
    // Do your calculations
    e.Graphics.DrawRectangle(Pens.LightBlue, px, py, wx, wy);
}

Como señaló @AndersForsgren para usar el CreateGraphics El método no es común y, por lo general, no necesita llamarlo (con la excepción señalada antes y cuando, por ejemplo, necesita realizar algunos cálculos basados ​​​​en los gráficos como para AutoSize).

contestado el 22 de mayo de 12 a las 16:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.