Idalgo Cantelli

.NET programming

  Home :: Contact :: Syndication  :: Login
  12 Posts :: 0 Stories :: 0 Comments :: 403 Trackbacks

Ho installato – un po’ in ritardo – la Beta 2 di Visual Studio 2005 e ho iniziato a esplorare le novità del mio namespace preferito: System.Drawing.

Chi lo ha già utilizzato per ottenere effetti grafici con le versioni precedenti del Framework sa che uno dei problemi principali è ridurre il flickering dei controlli su cui si compiono operazioni di disegno. Il modo classico per risolvere il problema è utilizzare il metodo SetStyle nel costruttore del nostro controllo Owner-draw:

 

    this.SetStyle(ControlStyles.UserPaint, true);

    this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);

    this.SetStyle(ControlStyles.DoubleBuffer, true);

    this.SetStyle(ControlStyles.ResizeRedraw, true);

 

 

La versione 2.0 del framework ha introdotto un oggetto che permette di gestire in maniera più flessibile le aree del controllo su cui vogliamo eseguire operazioni di disegno complesse.

Si tratta della classe BufferedGraphics. La classe non dispone di un costruttore pubblico, ma è possibile averne un’istanza chiamando il metodo Allocate della classe BufferedGraphicsContext.

Ogni Application Domain ha un suo BufferedGraphicsContext, a cui è possibile ottenere un riferimento tramite la proprietà statica BufferedGraphicsManager.Current:

 

 private BufferedGraphics bg = null;

 private BufferedGraphicsContext appDomainGraphicsContext;

 

 ///

 /// Costruttore.

 ///

 public Form1()

 {

     InitializeComponent();

     this.SetStyle(ControlStyles.ResizeRedraw, true);

           

appDomainGraphicsContext = BufferedGraphicsManager.Current;

 

bg = appDomainGraphicsContext.Allocate(this.CreateGraphics(),                                          this.ClientRectangle);

     bg.Render();

 

}

 

Come si vede dall’esempio, il metodo Allocate accetta come secondo parametro un oggetto Rectangle, il che significa che possiamo utilizzare il doppio buffer per una sottoarea specifica del nostro controllo (nell’esempio utilizziamo in realtà tutta l’area, con la proprietà ClientRectangle).

Una volta ottenuto l’oggetto BufferedGraphics, è possibile delegare ad esso operazioni di disegno che altrimenti genererebbero sfarfallìo (tipicamente succede quando la form viene ridimensionata, ma sarebbe il caso di usarlo anche qualora volessimo realizzare un CAD o delle animazioni).

Nell’esempio, si utilizza il metodo Paint per disegnare lo sfondo della Form sfumato e un’ellisse all’interno di essa. Se si ridimensiona il Form, l’immagine non presenta nessuno sfarfallìo.

 

 

private void Form1_Paint(object sender, PaintEventArgs e)

{

   using (LinearGradientBrush Linear = new LinearGradientBrush(this.ClientRectangle,

                        ProfessionalColors.ToolStripGradientBegin,

                        ProfessionalColors.ToolStripGradientEnd,

                        LinearGradientMode.Horizontal),

                       Linear2 = new LinearGradientBrush(this.ClientRectangle,

                       Color.Blue, Color.YellowGreen, LinearGradientMode.Vertical))

           

  {

    using (BufferedGraphics bg = appDomainGraphicsContext.Allocate (e.Graphics, this.ClientRectangle))

     {

        bg.Graphics.FillRectangle(Linear, this.ClientRectangle);

        bg.Graphics.DrawEllipse(new Pen(Linear2, 5), this.ClientRectangle);

        bg.Render();

     }

  }

}

?>

posted on martedì 24 maggio 2005 23.24