Graphics.Clear em um controle de formulário do Windows também limpa o próprio controle - como evitar isso?

StackOverflow https://stackoverflow.com//questions/10703678

Pergunta

Tento desenhar um retângulo de seleção personalizado em um Picturebox, usando o método abaixo:

    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);
        }
    }

Sempre que eu ligo:

g.Clear(Color.Transparent);

toda a caixa de imagem fica preta.No entanto, o retângulo é desenhado sobre ele.Se eu não chamar esse método, os retângulos serão empilhados sobre si mesmos, é claro.Quero remover o retângulo antigo e criar um novo como este.

Alguém pode descrever o que há de errado?

Foi útil?

Solução

Não pinte seu controle dentro de qualquer outro método que não seja OnPaintBackground ou OnPaint.

Na verdade, você pode precisar dele por motivos de desempenho (você não atualizará o controle completo, apenas alterará algo rapidamente), mas isso tornará seu código muito mais complicado e você sempre precisará fazer o mesmo trabalho dentro do Paint evento também (porque pode ser chamado por muitos outros motivos, então a saída deve ser a mesma).

Dentro de Paint você nem precisa usar CreateGraphics, o contexto gráfico está dentro do PaintEventArgs objeto, então mude seu código para:

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

Conforme apontado por @AndersForsgren para usar o CreateGraphics método não é comum e normalmente você não precisa chamá-lo (com exceção apontada antes e quando, por exemplo, você precisa realizar alguns cálculos baseados nos gráficos como no AutoSize).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top