Painting in Mono Winforms

Course- C# >

Painting in Mono Winforms

In this part of the Mono Winforms tutorial, we will do some painting. Painting is used, when we want to change or enhance an existing control. Or if we are creating a custom control from scratch. To do the painting, we use the painting API provided by the Winforms library. The painting is done within a method, that we plug into the Paint event.

The System.Drawing namespace provides access to GDI+ basic graphics functionality. More advanced functionality is provided in the System.Drawing.Drawing2D, System.Drawing.Imaging, and System.Drawing.Text namespaces. The Graphics class provides methods for drawing on the form.

Lines

Our first example will draw lines on the Form control.

lines.cs
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

class MForm : Form {

    public MForm() {
        Text = "Lines";
        Size = new Size(280, 270);
        ResizeRedraw = true;

        Paint += new PaintEventHandler(OnPaint);
        CenterToScreen();
    }


    void OnPaint(object sender, PaintEventArgs e)
    {      
        Graphics g = e.Graphics;
        Pen pen = new Pen(Color.Black, 1);

        pen.DashStyle = DashStyle.Dot;
        g.DrawLine(pen, 20, 40, 250, 40);

        pen.DashStyle = DashStyle.DashDot;
        g.DrawLine(pen, 20, 80, 250, 80);

        pen.DashStyle = DashStyle.Dash;
        g.DrawLine(pen, 20, 120, 250, 120);

        pen.DashStyle = DashStyle.DashDotDot;
        g.DrawLine(pen, 20, 160, 250, 160);

        pen.DashPattern = new float[] {6f, 8f, 1f, 1f, 1f, 1f, 1f, 1f };
        g.DrawLine(pen, 20, 200, 250, 200);

        g.Dispose();
    }
}

class MApplication {
    public static void Main() {
        Application.Run(new MForm());
    }
}

We draw five lines on the form. Each line has different DashStyle.

ResizeRedraw = true;

When we resize the form, it is automatically redrawn. This is not the default behavior.

Paint += new PaintEventHandler(OnPaint);

Paint events are delivered to the OnPaint() method.

void OnPaint(object sender, PaintEventArgs e)
{
    ... 
}

This is the signature of the OnPaint() method.

Graphics g = e.Graphics;

In order to paint on the form, we must get the Graphics object. Painting on a form is actually calling various methods of the Graphics object.

Pen pen = new Pen(Color.Black, 1);

pen.DashStyle = DashStyle.Dot;
g.DrawLine(pen, 20, 40, 250, 40);

We create a Pen object. This object is used to draw outlines of shapes. Than we set a dotted DashStyle. Finally we draw the line with the DrawLine() method. The first parameter is the pen object. The next four values are x and y values of starting and ending points of the line.

pen.DashPattern = new float[] {6f, 8f, 1f, 1f, 1f, 1f, 1f, 1f };

There are several built-in DashStyle values. We can create our own style by using the DashPattern property. It may look difficult at the first sight. But the pattern is simply an array of fill and empty values.

g.Dispose();

We know that C# language uses garbage collection. So why are we explicitly releasing resources? This is to increase efficiency. We are helping the garbage collector.

lines
Figure: Lines

Colors

A color in Winforms library represents an ARGB (alpha, red, green, blue) color. It is a combination of Alpha, Red, Green, and Blue (RGB) intensity values. There are also predefined color names that we can use in painting.

colors.cs
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

class MForm : Form {

    public MForm() {
        Text = "Colors";
        Size = new Size(360, 300);

        Paint += new PaintEventHandler(OnPaint);

        CenterToScreen();
    }


    void OnPaint(object sender, PaintEventArgs e)
    {      
        Graphics g = e.Graphics;
            
        g.FillRectangle(Brushes.Sienna, 10, 15, 90, 60);
        g.FillRectangle(Brushes.Green, 130, 15, 90, 60);
        g.FillRectangle(Brushes.Maroon, 250, 15, 90, 60);
        g.FillRectangle(Brushes.Chocolate, 10, 105, 90, 60);
        g.FillRectangle(Brushes.Gray, 130, 105, 90, 60);
        g.FillRectangle(Brushes.Coral, 250, 105, 90, 60);
        g.FillRectangle(Brushes.Brown, 10, 195, 90, 60);
        g.FillRectangle(Brushes.Teal, 130, 195, 90, 60);
        g.FillRectangle(Brushes.Goldenrod, 250, 195, 90, 60);

        g.Dispose();

    }
}

class MApplication {
    public static void Main() {
        Application.Run(new MForm());
    }
}

We draw nine rectangles with nine different colours.

g.FillRectangle(Brushes.Sienna, 10, 15, 90, 60);

The FillRectagle() method fills a specified rectangle with a brush. A brush can be a colour or a pattern. There are some predefined colours available. We can get them from the Brushes enumeration. The last four values are the x, y values of the topleft point and the width and height of the rectangle.

Colors
Figure: Colors

Hatches

The HatchBrush object is used to fill the interiors of the shapes. There are several built-in patterns that we can use.

hatches.cs
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

class MForm : Form {

    public MForm() {
        Text = "Hatches";
        Size = new Size(360, 300);

        Paint += new PaintEventHandler(OnPaint);

        CenterToScreen();
    }


    void OnPaint(object sender, PaintEventArgs e)
    {      
        Graphics g = e.Graphics;
            
        HatchBrush hb = new HatchBrush(HatchStyle.Cross, Color.Black, this.BackColor);
        g.FillRectangle(hb, 10, 15, 90, 60);

        hb = new HatchBrush(HatchStyle.Percent05, Color.Black, this.BackColor);
        g.FillRectangle(hb, 130, 15, 90, 60);

        hb = new HatchBrush(HatchStyle.SolidDiamond, Color.Black, this.BackColor);
        g.FillRectangle(hb, 250, 15, 90, 60);

        hb = new HatchBrush(HatchStyle.DiagonalBrick, Color.Black, this.BackColor);
        g.FillRectangle(hb, 10, 105, 90, 60);

        hb = new HatchBrush(HatchStyle.Divot, Color.Black, this.BackColor);
        g.FillRectangle(hb, 130, 105, 90, 60);

        hb = new HatchBrush(HatchStyle.Wave, Color.Black, this.BackColor);
        g.FillRectangle(hb, 250, 105, 90, 60);

        hb = new HatchBrush(HatchStyle.ZigZag, Color.Black, this.BackColor);
        g.FillRectangle(hb, 10, 195, 90, 60);

        hb = new HatchBrush(HatchStyle.Sphere, Color.Black, this.BackColor);
        g.FillRectangle(hb, 130, 195, 90, 60);

        hb = new HatchBrush(HatchStyle.Shingle, Color.Black, this.BackColor);
        g.FillRectangle(hb, 250, 195, 90, 60);

        hb.Dispose();
        g.Dispose();
    }
}

class MApplication {
    public static void Main() {
        Application.Run(new MForm());
    }
}

This time we fill nine rectangles with nine different patterns, called hatches.

HatchBrush hb = new HatchBrush(HatchStyle.Cross, Color.Black, this.BackColor);

Here we create a HatchBrush object. The parameters are the hatch style and the foreground and the background colours. The background colour is set to the colour of the form, so that it looks like we have drawn onto the form.

g.FillRectangle(hb, 10, 15, 90, 60);

We fill the rectangle with the specified hatch brush.

Hatches
Figure: Hatches

Gradients

In computer graphics, gradient is a smooth blending of shades from light to dark or from one color to another. In 2D drawing programs and paint programs, gradients are used to create colorful backgrounds and special effects as well as to simulate lights and shadows. (answers.com)

gradients.cs
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

class MForm : Form {

    public MForm() {
        Text = "Gradients";
        Size = new Size(350, 350);

        Paint += new PaintEventHandler(OnPaint);

        CenterToScreen();
    }


    void OnPaint(object sender, PaintEventArgs e)
    {      
        Graphics g = e.Graphics;

        Point pt1 = new Point(5, 5);
        Point pt2 = new Point(25, 25);
        Brush lg = new LinearGradientBrush(pt1, pt2, Color.Red, Color.Black);
        g.FillRectangle(lg, 20, 20, 300, 40);
        
        pt1 = new Point(5, 25);
        pt2 = new Point(20, 2);
        lg = new LinearGradientBrush(pt1, pt2, Color.Yellow, Color.Black);
        g.FillRectangle(lg, 20, 80, 300, 40);

        pt1 = new Point(5, 25);
        pt2 = new Point(2, 2);
        lg = new LinearGradientBrush(pt1, pt2, Color.Green, Color.Black);
        g.FillRectangle(lg, 20, 140, 300, 40);

        pt1 = new Point(25, 25);
        pt2 = new Point(15, 25);
        lg = new LinearGradientBrush(pt1, pt2, Color.Blue, Color.Black);
        g.FillRectangle(lg, 20, 200, 300, 40);
        
        pt1 = new Point(0, 10);
        pt2 = new Point(0, 20);
        lg = new LinearGradientBrush(pt1, pt2, Color.Orange, Color.Black);
        g.FillRectangle(lg, 20, 260, 300, 40);            

        lg.Dispose();
        g.Dispose();
    }
}

class MApplication {
    public static void Main() {
        Application.Run(new MForm());
    }
}

We draw five rectangles which are filled with different linear gradients.

Point pt1 = new Point(5, 5);
Point pt2 = new Point(25, 25);

These two are the controlling points of the linear gradient brush.

Brush lg = new LinearGradientBrush(pt1, pt2, Color.Red, Color.Black);

We create the LinearGradientBrush object. We use two controlling points and two blending colors.

Gradients
Figure: Gradients

Drawing string

To draw string on the Winforms Form, we use the DrawString() method.

lyrics.cs
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

class MForm : Form {

    public MForm() {

        Text = "You know I'm No Good";
        Size = new Size(380, 450);

        Paint += new PaintEventHandler(OnPaint);
        CenterToScreen();
    }


    void OnPaint(object sender, PaintEventArgs e)
    {      
        Graphics g = e.Graphics;
             
        Font ft = new Font("Purisa", 10);
        SolidBrush br = new SolidBrush(Color.Black);

        PointF pt = new PointF(20.0f, 20.0f);             
        g.DrawString("Meet you downstairs in the bar and heard", ft, br, pt);

        pt = new PointF(20.0f, 50.0f);             
        g.DrawString("Your rolled up sleeves and your skull t-shirt", ft, br, pt);

        pt = new PointF(20.0f, 80.0f);             
        g.DrawString("You say why did you do it with him today?", ft, br, pt);

        pt = new PointF(20.0f, 110.0f);             
        g.DrawString("And sniffed me out like I was tanqueray", ft, br, pt);

        pt = new PointF(20.0f, 160.0f);             
        g.DrawString("Cause you’re my fella, my guy", ft, br, pt);

        pt = new PointF(20.0f, 190.0f);             
        g.DrawString("Hand me your stella and fly", ft, br, pt);

        pt = new PointF(20.0f, 220.0f);             
        g.DrawString("By the time I’m out the door", ft, br, pt);

        pt = new PointF(20.0f, 250.0f);             
        g.DrawString("You tear me down like roger moore", ft, br, pt);

        pt = new PointF(20.0f, 300.0f);             
        g.DrawString("I cheated myself", ft, br, pt);

        pt = new PointF(20.0f, 330.0f);             
        g.DrawString("Like I knew I would", ft, br, pt);

        pt = new PointF(20.0f, 360.0f);             
        g.DrawString("I told ya, I was trouble", ft, br, pt);

        pt = new PointF(20.0f, 390.0f);             
        g.DrawString("You know that I’m no good", ft, br, pt);

        g.Dispose();
    }
}

class MApplication {
    public static void Main() {
        Application.Run(new MForm());
    }
}

In our example, we draw lyrics of a song on the Winforms form.

Font ft = new Font("Purisa", 10);

We use the Purisa font, of 10 pts height.

PointF pt = new PointF(20.0f, 20.0f);   

To draw string on the form, we must use floating point values.

g.DrawString("Meet you downstairs in the bar and heard", ft, br, pt);

The DrawString() method takes the following parameters: text to draw, font, brush and the PointF object.

Lyrics
Figure: Lyrics

Drawing image

In our last example we will draw an image on the Form control.

redrock.cs
 using System;
 using System.Drawing;
 using System.Windows.Forms;

class MForm : Form {

    private Bitmap castle;

    public MForm() {
        Text = "Red Rock";
        loadImage();
        ClientSize = new Size(castle.Width, castle.Height);

        Paint += new PaintEventHandler(OnPaint);

        CenterToScreen();
    }

    void loadImage() {
        try {    
            castle = new Bitmap("redrock.png");
        } catch (Exception e) {
            Console.WriteLine(e.Message);
            Environment.Exit(1);
        }
    }

    void OnPaint(object sender, PaintEventArgs e)
    {      
      Graphics g = e.Graphics;

      Rectangle r = new Rectangle(1, 1, castle.Width, castle.Height);
      g.DrawImage(castle, r);
    }
}

class MApplication {
    public static void Main() {
        Application.Run(new MForm());
    }
}

This code example draws an image of a castle on the form.

try {    
    castle = new Bitmap("redrock.png");
} catch (Exception e) {
    Console.WriteLine(e.Message);
    Environment.Exit(1);
}

We load an image of a castle.

Rectangle r = new Rectangle(1, 1, castle.Width, castle.Height);

We determine the rectangle that we will draw.

g.DrawImage(castle, r);

This line actually draws the image.

Image
Figure: Image

In this chapter, we did some painting in Mono Winforms library.