Leggi in inglese

Condividi tramite


BufferedGraphics Classe

Definizione

Fornisce un buffer grafico per il doppio buffer.

C#
public sealed class BufferedGraphics : IDisposable
Ereditarietà
BufferedGraphics
Implementazioni

Esempio

Nell'esempio di codice seguente viene illustrato l'uso di un BufferedGraphics oggetto per disegnare elementi grafici usando diversi tipi di implementazioni di buffering. Facendo clic sul modulo in alternativa viene avviato e arrestato un timer che causa aggiornamenti di disegno. Gli aggiornamenti di disegno consentono di osservare l'effetto del doppio buffering. Fare clic con il pulsante destro del mouse sul modulo per scorrere le modalità di disegno seguenti:

In ogni modalità viene disegnato testo che identifica la modalità corrente e descrive il comportamento che si verifica quando viene premuto ogni pulsante del mouse.

C#
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace BufferingExample
{
    public class BufferingExample : Form
    {
        private BufferedGraphicsContext context;
        private BufferedGraphics grafx;

    private byte bufferingMode;
    private string[] bufferingModeStrings =
        { "Draw to Form without OptimizedDoubleBufferring control style",
          "Draw to Form using OptimizedDoubleBuffering control style",
          "Draw to HDC for form" };

    private System.Windows.Forms.Timer timer1;
    private byte count;

        public BufferingExample() : base()
        {
            // Configure the Form for this example.
            this.Text = "User double buffering";
            this.MouseDown += new MouseEventHandler(this.MouseDownHandler);
            this.Resize += new EventHandler(this.OnResize);
            this.SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true );

            // Configure a timer to draw graphics updates.
        timer1 = new System.Windows.Forms.Timer();
        timer1.Interval = 200;
        timer1.Tick += new EventHandler(this.OnTimer);

        bufferingMode = 2;
        count = 0;

            // Retrieves the BufferedGraphicsContext for the
            // current application domain.
            context = BufferedGraphicsManager.Current;

            // Sets the maximum size for the primary graphics buffer
            // of the buffered graphics context for the application
            // domain.  Any allocation requests for a buffer larger
            // than this will create a temporary buffered graphics
            // context to host the graphics buffer.
            context.MaximumBuffer = new Size(this.Width+1, this.Height+1);

            // Allocates a graphics buffer the size of this form
            // using the pixel format of the Graphics created by
            // the Form.CreateGraphics() method, which returns a
            // Graphics object that matches the pixel format of the form.
            grafx = context.Allocate(this.CreateGraphics(),
                 new Rectangle( 0, 0, this.Width, this.Height ));

        // Draw the first frame to the buffer.
        DrawToBuffer(grafx.Graphics);
        }

    private void MouseDownHandler(object sender, MouseEventArgs e)
        {
        if( e.Button == MouseButtons.Right )
        {
                 // Cycle the buffering mode.
             if( ++bufferingMode > 2 )
                     bufferingMode = 0;

                 // If the previous buffering mode used
                 // the OptimizedDoubleBuffering ControlStyle,
                 // disable the control style.
                 if( bufferingMode == 1 )
                     this.SetStyle( ControlStyles.OptimizedDoubleBuffer, true );

                 // If the current buffering mode uses
                 // the OptimizedDoubleBuffering ControlStyle,
                 // enabke the control style.
                 if( bufferingMode == 2 )
                     this.SetStyle( ControlStyles.OptimizedDoubleBuffer, false );

                 // Cause the background to be cleared and redraw.
                 count = 6;
                 DrawToBuffer(grafx.Graphics);
         this.Refresh();
        }
        else
        {
                // Toggle whether the redraw timer is active.
        if( timer1.Enabled )
            timer1.Stop();
        else
            timer1.Start();
        }
        }

    private void OnTimer(object sender, EventArgs e)
    {
            // Draw randomly positioned ellipses to the buffer.
        DrawToBuffer(grafx.Graphics);

            // If in bufferingMode 2, draw to the form's HDC.
        if( bufferingMode == 2 )
                    // Render the graphics buffer to the form's HDC.
            grafx.Render(Graphics.FromHwnd(this.Handle));
            // If in bufferingMode 0 or 1, draw in the paint method.
        else
            this.Refresh();
    }

        private void OnResize(object sender, EventArgs e)
        {
           // Re-create the graphics buffer for a new window size.
           context.MaximumBuffer = new Size(this.Width+1, this.Height+1);
           if( grafx != null )
           {
           grafx.Dispose();
               grafx = null;
           }
           grafx = context.Allocate(this.CreateGraphics(),
               new Rectangle( 0, 0, this.Width, this.Height ));

           // Cause the background to be cleared and redraw.
           count = 6;
           DrawToBuffer(grafx.Graphics);
       this.Refresh();
        }	

    private void DrawToBuffer(Graphics g)
    {
            // Clear the graphics buffer every five updates.
        if( ++count > 5 )
            {
                count = 0;
                grafx.Graphics.FillRectangle(Brushes.Black, 0, 0, this.Width, this.Height);
            }

            // Draw randomly positioned and colored ellipses.
        Random rnd = new Random();
        for( int i=0; i<20; i++ )
        {
        int px = rnd.Next(20,this.Width-40);
        int py = rnd.Next(20,this.Height-40);
        g.DrawEllipse(new Pen(Color.FromArgb(rnd.Next(0, 255), rnd.Next(0,255), rnd.Next(0,255)), 1),
            px, py, px+rnd.Next(0, this.Width-px-20), py+rnd.Next(0, this.Height-py-20)); 	    			
        }

            // Draw information strings.
        g.DrawString("Buffering Mode: "+bufferingModeStrings[bufferingMode], new Font("Arial", 8), Brushes.White, 10, 10);
            g.DrawString("Right-click to cycle buffering mode", new Font("Arial", 8), Brushes.White, 10, 22);
            g.DrawString("Left-click to toggle timed display refresh", new Font("Arial", 8), Brushes.White, 10, 34);
    }

    protected override void OnPaint(PaintEventArgs e)
        {
        grafx.Render(e.Graphics);
    }

        [STAThread]
        public static void Main(string[] args)
        {
        Application.Run(new BufferingExample());
        }
    }
}

Commenti

La BufferedGraphics classe consente di implementare il doppio buffer personalizzato per la grafica. Fornisce un wrapper per un buffer grafico, insieme ai metodi che è possibile usare per scrivere nel buffer ed eseguirne il rendering in un dispositivo di output.

La grafica che usa il doppio buffer può ridurre o eliminare lo sfarfallio causato dalla ridisegnazione di una superficie di visualizzazione. Quando si usa il doppio buffer, gli elementi grafici aggiornati vengono prima di tutto disegnati in un buffer in memoria e il contenuto di questo buffer viene quindi scritto rapidamente in una o in tutta la superficie visualizzata. Questa sovrascrittura relativamente breve della grafica visualizzata in genere riduce o elimina lo sfarfallio che talvolta si verifica quando vengono aggiornati i grafici.

Nota

In .NET 6 e versioni successive, il pacchetto System.Drawing.Common, che include questo tipo, è supportato solo nei sistemi operativi Windows. L'uso di questo tipo nelle app multipiattaforma causa avvisi in fase di compilazione ed eccezioni di runtime. Per altre informazioni, vedere System.Drawing.Common supportato solo in Windows.

Nota

Il modo più semplice per usare il doppio buffer consiste nell'impostare il OptimizedDoubleBuffer flag di stile del controllo su un controllo utilizzando il SetStyle metodo . L'impostazione del OptimizedDoubleBuffer flag per un controllo reindirizza tutto il disegno per il controllo tramite un buffer grafico predefinito, senza richiedere codice aggiuntivo. Questo flag è impostato su true per impostazione predefinita.

La BufferedGraphics classe non ha un costruttore pubblico e deve essere creata da BufferedGraphicsContext per un dominio applicazione usando il relativo Allocate metodo. È possibile recuperare l'oggetto BufferedGraphicsContext per il dominio applicazione corrente dalla proprietà statica BufferedGraphicsManager.Current .

La Graphics proprietà può essere utilizzata per il disegno nel buffer grafico. Questa proprietà consente di accedere all'oggetto Graphics che disegna al buffer grafico allocato per questo BufferedGraphics oggetto.

Il Render metodo senza argomenti disegna il contenuto del buffer grafico nella superficie specificata al momento dell'allocazione del buffer. Altri overload del Render metodo consentono di specificare un Graphics oggetto o un IntPtr oggetto che punta a un contesto di dispositivo a cui disegnare il contenuto del buffer grafico.

Per altre informazioni sul disegno di grafica con doppio buffer, vedere Doppia grafica memorizzata nel buffer.

Proprietà

Graphics

Ottiene un oggetto Graphics con output nel buffer grafico.

Metodi

Dispose()

Rilascia tutte le risorse usate dall'oggetto BufferedGraphics.

Equals(Object)

Determina se l'oggetto specificato è uguale all'oggetto corrente.

(Ereditato da Object)
Finalize()

Consente a un oggetto di effettuare un tentativo di liberare risorse ed eseguire altre operazioni di pulizia prima che venga recuperato da Garbage Collection.

GetHashCode()

Funge da funzione hash predefinita.

(Ereditato da Object)
GetType()

Ottiene l'oggetto Type dell'istanza corrente.

(Ereditato da Object)
MemberwiseClone()

Crea una copia superficiale dell'oggetto Object corrente.

(Ereditato da Object)
Render()

Scrive il contenuto del buffer grafico nel dispositivo predefinito.

Render(Graphics)

Scrive il contenuto del buffer grafico nell'oggetto specificato Graphics.

Render(IntPtr)

Scrive il contenuto del buffer grafico nel contesto di dispositivo associato all'handle IntPtr specificato.

ToString()

Restituisce una stringa che rappresenta l'oggetto corrente.

(Ereditato da Object)

Si applica a

Prodotto Versioni
.NET Framework 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
Windows Desktop 3.0, 3.1, 5, 6, 7, 8, 9

Thread safety

La classe BufferedGraphics non è thread-safe. Quando si accede a un buffer grafico da thread separati, è importante usare un meccanismo di controllo di accesso ai thread per evitare conflitti.

Vedi anche