Clearing DrawRectangle no Windows Forms
-
13-09-2019 - |
Pergunta
Estou desenhando um retângulo, dormir por alguns milisegundos - então eu quero limpar o retângulo, mas eu não consigo descobrir como. (O retângulo está sentado sobre um gráfico, então não posso simplesmente cobri-lo com outro retângulo)
graphics.DrawRectangle(p, innerRectangle)
System.Threading.Thread.Sleep(75)
Next I want to clear the rectange...
Solução
Você precisa redesenhar o gráfico (ou pelo menos a parte dela sob o retângulo). Se esta é uma caixa de imagem ou algo semelhante, o uso Invaldiate () para forçar um repaint.
Outras dicas
Se o retângulo está sentado completamente sobre o gráfico que você deve ser capaz de apenas redesenhar ou atualizar o gráfico subjacente. Se não for, você vai precisar para redesenhar o retângulo usando a cor de fundo e, em seguida, atualizar o gráfico subjacente.
Eu acho que ele deve funcionar para copiar os dados originais a partir da superfície em um bitmap temporário antes de desenhar o retângulo, e depois tirar a parte de trás bitmap no lugar.
Atualizar
Já existe uma resposta aceita, mas eu pensei que eu pudesse compartilhar um exemplo de código de qualquer maneira. Este desenha o retângulo dado em vermelho no comando dado, e restaura a área depois 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;
}
I teve o mesmo problema e resolvido com um painel extra desenhada na forma principal e mostrado / escondido, dimensionados e posicionados como necessário.
SelectionBox box = new SelectionBox();
box.Location = location;
box.Size = size;
box.Visible = true;
Então, quando retângulo não é mais necessário, simplesmente escondê-lo chamando:
box.Visible = false;
A classe painel é feito com transparência para assegurar que os gráficos de sobreposição não escondem outros conteúdos da janela.
[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;
}
}
}