Pergunta

Como posso definir o protegido DoubleBuffered propriedade dos controles em um formulário que está sofrendo de cintilação?

Foi útil?

Solução

Aqui está uma versão mais genérica de Solução do manequim.

Podemos usar a reflexão para chegar ao protegido DoubleBuffered propriedade e, em seguida, pode ser definido como verdadeiro.

Observação:Você deve pague seus impostos de desenvolvedor e não use buffer duplo se o usuário estiver executando em uma sessão de serviços de terminal (por exemplo.Área de Trabalho Remota) Este método auxiliar não ativará o buffer duplo se a pessoa estiver executando na área de trabalho remota.

public static void SetDoubleBuffered(System.Windows.Forms.Control c)
{
   //Taxes: Remote Desktop Connection and painting
   //http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx
   if (System.Windows.Forms.SystemInformation.TerminalServerSession)
      return;

   System.Reflection.PropertyInfo aProp = 
         typeof(System.Windows.Forms.Control).GetProperty(
               "DoubleBuffered", 
               System.Reflection.BindingFlags.NonPublic | 
               System.Reflection.BindingFlags.Instance);

   aProp.SetValue(c, true, null); 
}

Outras dicas

Verificar este tópico

Repetindo o núcleo dessa resposta, você pode ativar o sinalizador de estilo WS_EX_COMPOSITED na janela para obter o formulário e todos os seus controles com buffer duplo.A bandeira de estilo está disponível desde o XP.Isso não torna a pintura mais rápida, mas a janela inteira é desenhada em um buffer fora da tela e exibida na tela de uma só vez.Fazendo com que pareça instantâneo aos olhos do usuário, sem artefatos de pintura visíveis.Não é totalmente isento de problemas, alguns renderizadores de estilos visuais podem apresentar falhas, principalmente o TabControl quando possui muitas guias.YMMV.

Cole este código em sua classe de formulário:

protected override CreateParams CreateParams {
    get {
        var cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;    // Turn on WS_EX_COMPOSITED
        return cp;
    } 
}

A grande diferença entre esta técnica e o suporte de buffer duplo do Winform é que a versão do Winform só funciona em um controle por vez.Você ainda verá cada controle individual se pintar.O que também pode parecer um efeito de cintilação, principalmente se o retângulo de controle não pintado contrastar mal com o plano de fundo da janela.

System.Reflection.PropertyInfo aProp = typeof(System.Windows.Forms.Control)
    .GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic |
    System.Reflection.BindingFlags.Instance);
aProp.SetValue(ListView1, true, null);

Ian tem mais algumas informações sobre como usar isso em um servidor de terminal.

public void EnableDoubleBuffering()
{
   this.SetStyle(ControlStyles.DoubleBuffer | 
      ControlStyles.UserPaint | 
      ControlStyles.AllPaintingInWmPaint,
      true);
   this.UpdateStyles();
}

Uma maneira é estender o controle específico que você deseja armazenar em buffer duplo e definir a propriedade DoubleBuffered dentro do ctor do controle.

Por exemplo:

class Foo : Panel
{
    public Foo() { DoubleBuffered = true; }
}

nobugz recebe o crédito pelo método no link dele, estou apenas repassando.Adicione esta substituição ao formulário:

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;
        return cp;
    }
}

Isso funcionou melhor para mim, no Windows 7 eu estava recebendo grandes blocos pretos aparecendo quando redimensionava um formulário de controle pesado.O controle agora salta!Mas é melhor.

Método de extensão para ativar ou desativar o buffer duplo para controles

public static class ControlExtentions
{
    /// <summary>
    /// Turn on or off control double buffering (Dirty hack!)
    /// </summary>
    /// <param name="control">Control to operate</param>
    /// <param name="setting">true to turn on double buffering</param>
    public static void MakeDoubleBuffered(this Control control, bool setting)
    {
        Type controlType = control.GetType();
        PropertyInfo pi = controlType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
        pi.SetValue(control, setting, null);
    }
}

Uso (por exemplo, como tornar o DataGridView DoubleBuffered):

DataGridView _grid = new DataGridView();
//  ...
_grid.MakeDoubleBuffered(true);

Antes de tentar o buffer duplo, veja se SuspendLayout()/ResumeLayout() resolve seu problema.

Isso me causou um muito de luto por dois dias com controle de terceiros até que eu o localizei.

protected override CreateParams CreateParams
{
    get
    {
        CreateParams cp = base.CreateParams;
        cp.ExStyle |= 0x02000000;
        return cp;
    }
}

Recentemente tive muitos furos (excrementos) ao redimensionar/redesenhar um controle contendo vários outros controles.

Tentei WS_EX_COMPOSITED e WM_SETREDRAW mas nada funcionou até usar isto:

private void myPanel_SizeChanged(object sender, EventArgs e)
{
     Application.DoEvents();
}

Só queria passar adiante.

Versão vb.net desta excelente solução....:

Protected Overrides ReadOnly Property CreateParams() As CreateParams
    Get
        Dim cp As CreateParams = MyBase.CreateParams
        cp.ExStyle = cp.ExStyle Or &H2000000
        Return cp
    End Get
End Property

Você também pode herdar os controles em suas próprias classes e definir a propriedade nelas.Este método também é bom se você tende a fazer muitas configurações iguais em todos os controles.

Descobri que simplesmente definir a configuração DoubleBuffered no formulário define automaticamente todas as propriedades listadas aqui.

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