Como duplicar controles .NET em buffer em um formulário?
-
09-06-2019 - |
Pergunta
Como posso definir o protegido DoubleBuffered
propriedade dos controles em um formulário que está sofrendo de cintilação?
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.