2014-06-17 1 views
0

Je me demandais si quelqu'un pouvait m'expliquer comment doubler un tampon dans un framework compact .net. J'ai trouvé des exemples de double tampon, mais je n'arrive pas à en faire fonctionner un seul.Double mise en mémoire tampon sur .NET Compact Framework

Nous avons créé une application avec de multiples formes. Certaines de ces formes prennent beaucoup de temps à dessiner à l'écran, ce qui entraîne un scintillement. Pour vous donner un aperçu de notre application, je vais vous expliquer l'un des formulaires. Ce formulaire contient un contrôle utilisateur, des panneaux, des zones de texte et des boutons. La commande usercontrol a des panneaux qui ont un dessin personnalisé (dessin du texte et des images (avec transparence) à l'écran). Et même certains de ces panneaux contiennent d'autres panneaux qui font la même chose. Les panneaux ont également un dessin personnalisé car nous dessinons du texte à l'écran avec quelques effets, etc. Chaque panneau prend du temps à dessiner, ce qui signifie que si nous avons 9 panneaux dans une grille 3x3, ils sont dessinés et affichés dans un ordre aléatoire. d'être affiché tout en même temps. Il en va de même avec le dessin de texte, etc. Nous aimerions que tout soit affiché sur le formulaire en même temps.

Donc, ma question est, puis-je créer une classe «super» qui fait le double tampon, faire le dessin en mémoire du formulaire complet? Puis-je prolonger mes formulaires d'application sans devoir modifier quoi que ce soit à mes commandes, panneaux, dessins, etc.?

Merci

+0

Je ne connais que DoubleBuffering pour les images qui ne sont pas pour les éléments Windows comme les boutons, les champs de saisie, etc. Vous pouvez conserver une pile de formulaires en mémoire, puis passer rapidement entre eux. Il existe un exemple sur MSDN. – josef

Répondre

3

Je ne suis pas sûr de les subtilités de votre forme exacte avec tous les contrôles, mais j'ai mis en place une base DoubleBufferableControl classe à partir de laquelle vous pouvez l'étendre pour créer des contrôles personnalisés qui sont le double tamponné. J'ai créé de nombreux contrôles avec des dessins personnalisés qui tous utilisent ceci comme classe de base.

Vous pouvez utiliser cette classe comme classe de base de vos contrôles qui ont une peinture personnalisée pour éviter le scintillement. Dans votre classe enfant, veillez à définir DoubleBuffered sur true dans le constructeur.

/// <summary> 
/// Implements the functionality for a control that can be double buffered 
/// </summary> 
public class DoubleBufferableControl : ScrollableControl 
{ 
    public event BufferedPaintEventHandler BufferedPaint; 
    private bool doubleBuffered; 
    private Bitmap backBuffer; 
    private Size oldSize; 

    /// <summary> 
    /// Gets or sets whether this control will use double buffering 
    /// </summary> 
    public bool DoubleBuffered 
    { 
     get 
     { 
      return doubleBuffered; 
     } 
     set 
     { 
      if (value && !doubleBuffered && Width > 0 && Height > 0) 
      { 
       backBuffer = new Bitmap(Width, Height); 
      } 
      else if(!value && doubleBuffered) 
      { 
       backBuffer.Dispose(); 
       backBuffer = null; 
      } 

      doubleBuffered = value; 
     } 
    } 

    /// <summary> 
    /// Gets the off screen image used for double buffering 
    /// </summary> 
    public Bitmap BackBuffer 
    { 
     get 
     { 
      return backBuffer; 
     } 
    } 

    /// <summary> 
    /// Initializes a new instance of the <see cref="DoubleBufferableControl"/> class. 
    /// </summary> 
    public DoubleBufferableControl() 
    { 
     AutoScroll = false; 
     doubleBuffered = DefaultDoubleBuffered; 
     oldSize = Size; 
    } 

    #region Designer 
    private bool DefaultDoubleBuffered = false; 
    protected virtual bool ShouldSerializeDoubleBuffered() 
    { 
     return !this.doubleBuffered.Equals(DefaultDoubleBuffered); 
    } 
    protected void ResetDoubleBuffered() 
    { 
     DoubleBuffered = DefaultDoubleBuffered; 
    } 
    #endregion 

    /// <summary> 
    /// Raises the Paint event 
    /// </summary> 
    /// <param name="e">A PaintEventArgs that represents event data</param> 
    protected override sealed void OnPaint(PaintEventArgs e) 
    { 
     if (doubleBuffered) 
     { 
      DoubleBufferedPaintEventArgs pe = new DoubleBufferedPaintEventArgs(CreateGraphics(), e.ClipRectangle); 
      OnPaint(pe); 
      pe.Graphics.Dispose(); 
      e.Graphics.DrawImage(backBuffer, e.ClipRectangle, e.ClipRectangle, GraphicsUnit.Pixel); 
      base.OnPaint(e); 
     } 
     else 
     { 
      DoubleBufferedPaintEventArgs pe = new DoubleBufferedPaintEventArgs(e.Graphics, e.ClipRectangle); 
      OnPaint(pe); 
      base.OnPaint(e); 
     } 
    } 

    /// <summary> 
    /// Raises the Paint event for child classes that are to be double buffered 
    /// </summary> 
    /// <param name="e"></param> 
    protected virtual void OnPaint(DoubleBufferedPaintEventArgs e) 
    { 
     if (BufferedPaint != null) 
      BufferedPaint(this, e); 
    } 

    /// <summary> 
    /// Paints the background of the control 
    /// </summary> 
    /// <param name="e">A PaintEventArgs object that contains event data</param> 
    protected override void OnPaintBackground(PaintEventArgs e) 
    { 
     // do not use arg, because can't control back/screen 
     Graphics gfx = CreateGraphics(); 
     gfx.Clear(BackColor); 
     gfx.Dispose(); 
    } 

    /// <summary> 
    /// Raises the Resize event 
    /// </summary> 
    /// <param name="e">An EventArgs that represents event data</param> 
    protected override void OnResize(System.EventArgs e) 
    { 
     if (Size != oldSize) // Stupid control gets resized when like anything happens to the parent form 
     { 
      if (doubleBuffered) 
      { 
       if (backBuffer != null) 
        backBuffer.Dispose(); 

       backBuffer = new Bitmap(Width != 0 ? Width : 1, Height != 0 ? Height : 1); 
      } 
     } 
     oldSize = Size; 

     base.OnResize(e); 
    } 

    /// <summary> 
    /// Creates the Graphics for the control 
    /// </summary> 
    /// <param name="backBuffer">True to bypass the buffer and get the control graphics</param> 
    /// <returns></returns> 
    public virtual Graphics CreateGraphics(bool bypass) 
    { 
     if(bypass || !doubleBuffered) 
      return base.CreateGraphics(); 
     else 
      return Graphics.FromImage(backBuffer); 
    } 
    public virtual new Graphics CreateGraphics() 
    { 
     return CreateGraphics(false); 
    } 
} 

et vous en aurez besoin:

/// <summary> 
/// Provides data for the DoubleBufferedControl.Paint event 
/// </summary> 
public class DoubleBufferedPaintEventArgs : PaintEventArgs 
{ 
    /// <summary> 
    /// Initializes a DoubleBufferedPaintEventArgs 
    /// </summary> 
    /// <param name="g">The Graphics object to paint to; If the control is double buffered, the graphics object is for the buffer otherwise the screens graphics is used</param> 
    /// <param name="clip">The region in which to paint</param> 
    public DoubleBufferedPaintEventArgs(Graphics g, Rectangle clip) : base(g, clip) { } 
} 
public delegate void BufferedPaintEventHandler(object sender, DoubleBufferedPaintEventArgs args); 

je hérite généralement de cette classe, remplacer la méthode OnPaintBackground et laisser son vide de mise en œuvre. Ensuite, j'implémente tout le dessin personnalisé dans la méthode OnPaint.

Questions connexes