2009-02-04 5 views
1

Je sais que le double tampon est un sujet souvent parlé, mais peu importe combien j'ai cherché et essayé différentes approches, je ne peux toujours pas obtenir le contrôle de se re-dessiner sans scintillement. Voici mon code:Problèmes de redessiner une image sur un contrôle à double tampon sans scintillement

using System; 
using System.Drawing; 
using System.Windows.Forms; 

namespace Emgu.UI 
{ 
    public class DoubleBufferedPictureBox : Control 
    { 
     const BufferedGraphics NO_MANAGED_BACK_BUFFER = null; 

     BufferedGraphicsContext GraphicManager; 
     BufferedGraphics ManagedBackBuffer; 

     public Bitmap Bitmap { get; set; } 
     public Rectangle DrawRectangle { get; set; } 

     public DoubleBufferedPictureBox() 
     { 
      SetStyle(ControlStyles.AllPaintingInWmPaint, true); 

      GraphicManager = BufferedGraphicsManager.Current; 
      GraphicManager.MaximumBuffer = 
        new Size(Width + 1, Height + 1); 
      ManagedBackBuffer = 
       GraphicManager.Allocate(CreateGraphics(), 
               ClientRectangle); 

      Resize += DoubleBufferedPictureBox_Resize; 
     } 

     void DoubleBufferedPictureBox_Resize(object sender, EventArgs e) 
     { 
      if (ManagedBackBuffer != NO_MANAGED_BACK_BUFFER) 
       ManagedBackBuffer.Dispose(); 

      GraphicManager.MaximumBuffer = 
        new Size(Width + 1, Height + 1); 

      ManagedBackBuffer = 
       GraphicManager.Allocate(CreateGraphics(), 
               ClientRectangle); 
      Refresh(); 
     } 

     protected override void OnPaint(PaintEventArgs pe) 
     { 
      ManagedBackBuffer.Graphics.DrawImage(Bitmap, DrawRectangle); 
      ManagedBackBuffer.Render(pe.Graphics); 
     } 

    } 
} 

Des idées?

+0

Si vous définissez l'indicateur OptimizedDoubleBuffer, vous devez également définir l'indicateur UserDraw. Avez-vous essayé cela? –

Répondre

0

Avez-vous essayé de définir la propriété DoubleBuffered sur true?

+0

Oui, j'ai. Essayé à nouveau maintenant pour une bonne mesure - mêmes résultats ... –

+0

Qu'en est-il de votre méthode SetStyles? ex: SetStyles (ControlStyles.AllPaintingInWmPaint | ControlSyles.DoubleBuffer, true); – scottm

+0

ControlStyles.DoubleBuffer est à partir de 1.1 - J'ai utilisé OptimizedDoubleBuffer de 2.0 sans effet ... –

0

Est-ce que la peinture dans le contrôle parent (Formulaire?) Est également double-tamponnée?

Votre contrôle personnalisé peut être peint sans scintillement mais plus loin lorsque le contrôle parent est peint et n'est pas à double tampon, il scintille.

Il se peut que vous doublez la mauvaise chose.

+0

Juste essayé aussi, pas d'effet. –

+0

Pouvez-vous télécharger quelque part le code que vous essayez afin que nous puissions le bricoler? – arul

+0

Hm - J'essaie de re-produire ceci et cela s'avère dur - le PictureBox est contenu dans un autre contrôle que je n'ai pas conçu moi-même et c'est de là que vient le scintillement - j'étudie plus maintenant. –

0

Je pense que le problème est dans votre méthode OnPaint, from MSDN, lorsque vous appelez votre méthode de ManagedBackBuffer.Render, vous devez passer CreateGraphics() pas la propriété Graphics:

+0

Rien :(Combien cela peut-il être difficile, n'est-ce pas? –

2

Oh mon Dieu ...

Comme je l'ai dit dans mes commentaires, le PictureBox est contenu dans un autre contrôle que je n'ai pas écrit (mais dont j'ai la source). Il se trouve que le scintillement est causée par ces deux lignes:

if (pictureBox.Width != _displayedImage.Width) pictureBox.Width = _displayedImage.Width; 
if (pictureBox.Height != _displayedImage.Height) pictureBox.Height = _displayedImage.Height; 

Je pense que ce parce que le PictureBox est effectivement arrimé dans le contrôle parent ...

De toute façon, merci pour toutes vos réponses.

+0

Vous voudrez probablement faire les deux en même temps - c'est-à-dire pictureBox.Size = _displayedImage.Size. – mquander

2

Utilisez-vous .Net 2.0? Si c'est le cas, j'ai trouvé que les styles de fenêtres suivants font l'affaire, même avec les anciens contrôles stuborn Win32 intégrés, et c'est rapide aussi!

// Note the >>> Optimized <<< DoubleBuffer 
SetStyle(ControlStyles.OptimizedDoubleBuffer, true); 
SetStyle(ControlStyles.AllPaintingInWmPaint, true); 
SetStyle(ControlStyles.ResizeRedraw, true); 
SetStyle(ControlStyles.UserPaint, true); 

Assurez-vous toujours tirage au sort de l'intérieur d'un message WM_PAINT, sinon il se met à clignoter. Vous n'avez pas besoin d'autre chose, tout est automatique.

Questions connexes