Domanda

Come posso impostare il file protected DoubleBuffered proprietà dei controlli su un modulo che soffrono di sfarfallio?

È stato utile?

Soluzione

Ecco una versione più generica di La soluzione di Dummy.

Possiamo usare la riflessione per arrivare a ciò che è protetto Doppio buffer proprietà, e quindi può essere impostato su VERO.

Nota:Dovresti pagare le tasse allo sviluppatore e non utilizzare il doppio buffer se l'utente è in esecuzione in una sessione di servizi terminal (per esempio.Desktop remoto) Questo metodo di supporto non attiverà il doppio buffering se la persona è in esecuzione sul desktop remoto.

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

Altri suggerimenti

Controllo questo filo

Ripetendo il nucleo di quella risposta, puoi attivare il flag di stile WS_EX_COMPOSITED sulla finestra per ottenere il doppio buffer sia del modulo che di tutti i suoi controlli.Il flag di stile è disponibile a partire da XP.Non rende la pittura più veloce, ma l'intera finestra viene disegnata in un buffer fuori schermo e visualizzata sullo schermo in un colpo solo.Rendendolo istantaneo agli occhi dell'utente senza artefatti pittorici visibili.Non è del tutto esente da problemi, alcuni renderer di stili visivi possono presentare problemi, in particolare TabControl quando ha troppe schede.YMMV.

Incolla questo codice nella classe del modulo:

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

La grande differenza tra questa tecnica e il supporto del doppio buffering di Winform è che la versione di Winform funziona solo su un controllo alla volta.Vedrai comunque ogni singolo controllo dipingere se stesso.Anche questo può sembrare un effetto di sfarfallio, in particolare se il rettangolo di controllo non dipinto contrasta male con lo sfondo della finestra.

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 ha alcune informazioni in più sull'utilizzo su un server terminal.

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

Un modo è estendere il controllo specifico di cui desideri eseguire il doppio buffer e impostare la proprietà DoubleBuffered all'interno del ctor del controllo.

Ad esempio:

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

nobugz ottiene il merito per il metodo nel suo collegamento, lo sto solo ripubblicando.Aggiungi questa sostituzione al modulo:

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

Questo ha funzionato meglio per me, su Windows 7 apparivano grandi blocchi neri quando ridimensionavo un modulo pesante di controllo.Il controllo ora invece rimbalza!Ma è meglio.

Metodo di estensione per attivare o disattivare il doppio buffering per i controlli

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

Utilizzo (ad esempio come rendere DataGridView DoubleBuffered):

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

Prima di provare il doppio buffering, verifica se SuspendLayout()/ResumeLayout() risolve il tuo problema.

Questo mi ha causato a quantità di dolore per due giorni con un controllo di terze parti finché non l'ho rintracciato.

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

Recentemente ho riscontrato molti buchi (escrementi) durante il ridimensionamento/ridisegno di un controllo contenente diversi altri controlli.

Ho provato WS_EX_COMPOSITED e WM_SETREDRAW ma niente ha funzionato finché non ho usato questo:

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

Volevo solo trasmetterlo.

Versione vb.net di questa ottima soluzione....:

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

Puoi anche ereditare i controlli nelle tue classi e impostare la proprietà lì.Questo metodo è utile anche se tendi a eseguire molte impostazioni uguali su tutti i controlli.

Ho scoperto che semplicemente impostando l'impostazione DoubleBuffered nel modulo vengono impostate automaticamente tutte le proprietà elencate qui.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top