The Graphics Object

All drawing in GDI+ takes place upon the Graphics object and there are several contexts in which you'll find one. During a Paint cycle the Graphics object will be provided in a PaintEventArgs object that is handed to your code in the OnPaint and OnPaintBackground methods of a Windows Forms control. This same event argument is passed to handlers that service the Paint event raised by the OnPaint methods. When printing, the PrintPageEventArgs provided in a PrintPage event will contain a Graphics object for the printer and you can obtain a Graphics object for certain types of image so that you can paint directly on an image in memory as if it were the screen.

Obtaining the Graphics object.

When you're writing programs that place graphics on screen the graphics object will be handed to you wrapped up in a PaintEventArgs object. There are two ways in which your code can get hold of the Graphics object. You can override the protected OnPaint or OnPaintBackground methods or you can add a handler to the Paint event. In all these cases the Graphics object is passed in a PaintEventArgs object. Listing 1 shows the various methods.

Listing 1

    protected override void OnPaint(PaintEventArgs e)

    {

      //get the Graphics object from the PaintEventArgs

      Graphics g=e.Graphics;

      g.DrawLine(....);

 

      //or use it directly

      e.Graphics.DrawLine(....);

      

      //Remember to call the base class or the Paint event won't fire

      base.OnPaint (e);

    }

 

    //This is the Paint event handler

    private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)

    {

      //get the Graphics object from the PaintEventArgs

      Graphics g=e.Graphics;

      g.DrawLine(....);

 

      //or use it directly

      e.Graphics.DrawLine(....);

    } 

    Protected Overrides Sub OnPaint(e As PaintEventArgs)

     'get the Graphics object from the PaintEventArgs

     Dim g As Graphics = e.Graphics

     g.DrawLine(....)

     

     'or use it directly

     e.Graphics.DrawLine(....)

     

     'Remember to call the base class or the Paint event won't fire

     MyBase.OnPaint(e)

    End Sub 'OnPaint

    

    

    'This is the Paint event handler

    Private Sub Form1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint

     'get the Graphics object from the PaintEventArgs

     Dim g As Graphics = e.Graphics

     g.DrawLine(....)

     

     'or use it directly

     e.Graphics.DrawLine(....)

    End Sub 'Form1_Paint

You can see in Listing 1 that you can get a reference to the Graphics object and save that for use in the code or use it directly from the PaintEventArgs. Remember not to save the Graphics object outside of the scope of the method.

What to do with it when you have it.

When your code has access to a Graphics object there are a number of things you can do. They fall into five general categories.

  • Stroke a shape. Shapes such as rectangles, ellipses and lines are drawn using a Pen object. The pen can have different thickness or colour and have many other attributes which you will see in another article.

  • Fill a shape. Shapes can be filled with a Brush object. Brushes have many complex settings in GDI+ but they all basically fill an area with colour.

  • Draw a string. Text can be placed on the Graphics surface using the DrawString method.

  • Draw an image. Images can be drawn in any scale using one of the DrawImage methods.

  • Modify the Graphics object. There are many methods that change the way the Graphics object performs. You can change the quality of graphics and have high-quality graphics at the expense of speed. You can change the way the graphics are output to create rotation, zooming or distortion effects.

To demonstrate the use of the Graphics object, the following listing shows the paint handler from a form that demonstrates stroking and filling of shapes. Figure 1 shows this simple application at work.

Figure 1. Stroking and filling.

    protected override void OnPaint(PaintEventArgs e)

    {

      //Get the Graphics object

      Graphics g=e.Graphics;

 

      //Draw a line

      g.DrawLine(Pens.Red,10,5,110,15);

 

      //Draw an ellipse

      g.DrawEllipse(Pens.Blue,10,20,110,45);

 

      //Draw a rectangle

      g.DrawRectangle(Pens.Green,10,70,110,45);

 

      //Fill an ellipse

      g.FillEllipse(Brushes.Blue,130,20,110,45);

 

      //Fill a rectangle

      g.FillRectangle(Brushes.Green,130,70,110,45);

 

      base.OnPaint (e);

    }

 

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)

      'Get the Graphics object

      Dim g As Graphics = e.Graphics

 

      'Draw a line

      g.DrawLine(Pens.Red, 10, 5, 110, 15)

 

      'Draw an ellipse

      g.DrawEllipse(Pens.Blue, 10, 20, 110, 45)

 

      'Draw a rectangle

      g.DrawRectangle(Pens.Green, 10, 70, 110, 45)

 

      'Fill an ellipse

      g.FillEllipse(Brushes.Blue, 130, 20, 110, 45)

 

      'Fill a rectangle

      g.FillRectangle(Brushes.Green, 130, 70, 110, 45)

 

      MyBase.OnPaint(e)

    End Sub 'OnPaint

 

Things to remember.

Generally, you should only ever use the Graphics object handed to you by the system.

GDI+ is an "Immediate Mode" system. This is to say that the Graphics object has no knowledge of objects, only areas of colour. Shapes and lines are only remembered until they are painted over by a different colour.

You should not store a Graphics object outside of the scope of the method that its given to. When drawing is done, the Graphics object is destroyed until another is needed.

 


Return to the Beginners Guide index.