2009-06-11 57 views
5

Estoy dibujando un rectángulo, durmiendo durante unos milisegundos, luego quiero borrar el rectángulo, pero no puedo entender cómo. (El rectángulo está sentado sobre un gráfico así que no puedo simplemente cubrirlo con otro rectángulo)Borrando DrawRectangle en Windows Forms

   graphics.DrawRectangle(p, innerRectangle) 
       System.Threading.Thread.Sleep(75) 
       Next I want to clear the rectange... 

Respuesta

5

Es necesario volver a dibujar el gráfico (o al menos la parte de ella bajo el rectángulo). Si se trata de un cuadro de imagen o algo similar, use Invaldiate() para forzar el repintado.

2

Supongo que debería funcionar para copiar los datos originales de la superficie en un mapa de bits temporal antes de dibujar el rectángulo, y luego dibujar el mapa de bits en su lugar.

actualización

Ya existe una respuesta aceptada, pero pensé que podría compartir un ejemplo de código de todos modos. Éste dibuja el rectángulo dado en rojo en el control dado, y restaura el área después de 500 ms.

public void ShowRectangleBriefly(Control ctl, Rectangle rect) 
{ 
    Image toRestore = DrawRectangle(ctl, rect); 
    ThreadPool.QueueUserWorkItem((WaitCallback)delegate 
    { 
     Thread.Sleep(500); 
     this.Invoke(new Action<Control, Rectangle, Image>(RestoreBackground), ctl, rect, toRestore); 
    }); 
} 

private void RestoreBackground(Control ctl, Rectangle rect, Image image) 
{ 
    using (Graphics g = ctl.CreateGraphics()) 
    { 
     g.DrawImage(image, rect.Top, rect.Left, image.Width, image.Height); 
    } 
    image.Dispose(); 
} 

private Image DrawRectangle(Control ctl, Rectangle rect) 
{ 
    Bitmap tempBmp = new Bitmap(rect.Width + 1, rect.Height + 1); 
    using (Graphics g = Graphics.FromImage(tempBmp)) 
    { 
     g.CopyFromScreen(ctl.PointToScreen(new Point(rect.Top, rect.Left)), new Point(0, 0), tempBmp.Size); 
    } 

    using (Graphics g = this.CreateGraphics()) 
    { 
     g.DrawRectangle(Pens.Red, rect); 
    } 
    return tempBmp; 
} 
2

Si el rectángulo se encuentra completamente sobre el gráfico, debería poder volver a dibujar o actualizar el gráfico subyacente. Si no es así, tendrá que volver a dibujar el rectángulo utilizando el color de fondo, y luego actualizar el gráfico subyacente.

1

Tuve el mismo problema y lo resolví con un panel adicional dibujado en el formulario principal y se muestra/oculta, se dimensiona y se coloca según sea necesario.

SelectionBox box = new SelectionBox(); 
box.Location = location; 
box.Size = size; 
box.Visible = true; 

Luego, cuando rectángulo ya no es necesario, simplemente esconderlo llamando:

clase
box.Visible = false; 

El panel está hecho con transparencia para asegurar que los gráficos de superposición no oculta otro contenido de la ventana.

[System.ComponentModel.DesignerCategory("Code")] 
    public class SelectionBox : Panel 
    { 
    protected override void OnPaint(PaintEventArgs e) 
    { 
     const int penWidth = 2; 
     int offset = penWidth - 1; 
     using (Pen pen = new Pen(Color.Red, 2)) 
     e.Graphics.DrawRectangle(pen, offset, offset, 
      ClientSize.Width - offset - 1, ClientSize.Height - offset - 1); 
    } 

    protected override CreateParams CreateParams 
    { 
     get 
     { 
     CreateParams cp = base.CreateParams; 
     cp.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT 
     return cp; 
     } 
    } 
    } 
+0

Tenga en cuenta que en este caso el panel de superposición interceptará los clics del mouse, por lo que debe reenviar todos los eventos relevantes al panel subyacente. –