Question

Comment définir la propriété protégée DoubleBuffered des contrôles d'un formulaire souffrant de scintillement?

Était-ce utile?

La solution

Voici une version plus générique de la solution de Dummy .

Nous pouvons utiliser la réflexion pour accéder à la zone protégée DoubleBuffered , puis définissez-la sur true .

Remarque : vous devez payer votre développeur. taxes et non utiliser la mise en mémoire tampon double si l'utilisateur est en cours d'exécution une session de services de terminal (par exemple, Bureau à distance) Cette méthode d'assistance n'active pas la double mise en mémoire tampon si la personne s'exécute sur un bureau à distance.

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

Autres conseils

Vérifiez ce fil de discussion

En répétant l'essentiel de cette réponse, vous pouvez activer l'indicateur de style WS_EX_COMPOSITED dans la fenêtre pour obtenir le formulaire et tous ses contrôles dans la double mémoire tampon. Le drapeau de style est disponible depuis XP. Cela ne rend pas la peinture plus rapide, mais toute la fenêtre est dessinée dans une mémoire tampon hors écran et affichée à l'écran d'un coup. Le faire paraître instantanément aux yeux de l'utilisateur sans artefacts de peinture visibles. Ce n'est pas tout à fait sans problème, certains moteurs de rendu de styles visuels peuvent créer des problèmes, en particulier TabControl lorsqu'il contient trop d'onglets. YMMV.

Collez ce code dans votre classe de formulaire:

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

La grande différence entre cette technique et la prise en charge de la mise en mémoire tampon double de Winform réside dans le fait que la version de Winform ne fonctionne que sur un contrôle à la fois. Vous verrez toujours chaque peinture de contrôle elle-même. Cela peut également ressembler à un scintillement, en particulier si le rectangle de contrôle non peint contraste mal avec le fond de la fenêtre.

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 a quelques informations supplémentaires de l’utiliser sur un serveur de terminal.

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

Une solution consiste à étendre le contrôle spécifique que vous souhaitez utiliser comme double tampon et à définir la propriété DoubleBuffered dans le ctor du contrôle.

Par exemple:

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

nobugz obtient le crédit pour la méthode dans son lien, je ne fais que republier. Ajoutez ce remplacement au formulaire:

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

Cela fonctionnait mieux pour moi. Sous Windows 7, de gros blocs noirs apparaissaient lorsque je redimensionnais une forme lourde de contrôle. Le contrôle rebondit maintenant à la place! Mais c'est mieux.

Méthode d'extension pour activer ou désactiver la double mise en mémoire tampon pour les contrôles

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

Utilisation (par exemple, comment créer DataGridView DoubleBuffered):

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

Avant d’essayer la double mise en tampon, vérifiez si SuspendLayout () / ResumeLayout () résout votre problème.

Cela m'a causé beaucoup de chagrin pendant deux jours avec un contrôle par une tierce partie jusqu'à ce que je le retrouve.

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

J'ai récemment eu beaucoup de trous lors du redimensionnement / redessinage d'un contrôle contenant plusieurs autres contrôles.

J'ai essayé WS_EX_COMPOSITED et WM_SETREDRAW mais rien n'a fonctionné jusqu'à ce que je l'utilise:

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

Je voulais juste le transmettre.

Version vb.net de cette solution intéressante ....:

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

Vous pouvez également hériter des contrôles dans vos propres classes et y définir la propriété. Cette méthode est également utile si vous avez tendance à configurer de manière identique sur toutes les commandes.

J'ai constaté que le simple fait de définir le paramètre DoubleBuffered sur le formulaire définit automatiquement toutes les propriétés répertoriées ici.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top