oreilly.comSafari Books Online.Conferences.


O'Reilly Book Excerpts: Mono: A Developer's Notebook

How to Write a Basic Gtk# Program with Mono

Editor's note: O'Reilly's upcoming Mono: A Developer's Notebook walks you through nearly 50 mini-projects that will introduce you to the most important and compelling aspects of the 1.0 release. This article, which shows you how to install Mono on Windows, how Gtk# works, and how to write a simple Gtk# program, is just the sort of mini-project you'll find in the book.

Gtk# is the Mono API for the GTK+ user interface toolkit. While Mono implements Windows.Forms, Gtk# is a completely open source alternative, and the look-andfeel of choice for Mono programs running on Linux. This lab demonstrates how to install Mono on Windows and write a simple Gtk# program.

Any user interface programming toolkit defines a way for delivering events from the user to the program. Whereas with non-interactive programs the flow of control is under the programmer's direction, interactive programs must respond to the events they receive.

In Gtk#, the flow of control is governed by the main event loop. The program yields its control to the main loop, which is responsible for processing input events. Whenever events that the program is interested in happen, handlers for those events are called and control given to the main program.

Mono is an open source implementation of the Common Language Runtime. It includes the Gtk# user interface libraries.

How do I do that?

First, install Mono and Gtk# on your computer. The Mono Windows installer can be downloaded from The Gtk# Windows installer can be found linked from

Check you have the Visual C++ runtime, msvcr70.dll, in your C:\Windows directory. This can be downloaded for free from Microsoft.

Because Mono is still under aggressive development, issues arise periodically. Check out the Gtk# Windows Beginner's Guide, at Follow any instructions given there for the version of Gtk# you downloaded.

Now set up the MONO_PATH environmental variable to refer to the bin subdirectory of your Mono installation, for example C:\Program Files\Mono-0.31\bin. Ensure your PATH variable also includes this directory. Now that Mono is happily installed, on with the lab. We will construct a basic Gtk# program using a window and a button. Both of these raise events, and need add handlers for those that the programmer wants to process. Example 2 shows the program listing.

Example 2. Basic Gtk# application: 01-basics/Main.cs

// 04-gtk/01-basics
using System;
using Gtk;
class MainClass {
    public static void Main (string[] args)
        Application.Init ();
        Window w = new Window ("Gtk# Basics");
        Button b = new Button ("Hit me");
        w.DeleteEvent += new
        DeleteEventHandler (Window_Delete);
        b.Clicked += new
        EventHandler (Button_Clicked);
        // initialize the GUI
        w.Add (b);
        w.SetDefaultSize (200, 100);
        w.ShowAll ();
        Application.Run ();
    static void Window_Delete (object o,
        DeleteEventArgs args)
        Application.Quit ();
        args.RetVal = true;
    static void Button_Clicked (object o, EventArgs
        System.Console.WriteLine ("Hello, World!");

The -r:gtk-sharp option to the compiler causes it to reference the Gtk# assembly. Without it, the compiler wouldn't know where to find the Gtk classes.

Use a regular text editor to save the source in Main.cs and compile it like this:

$ mcs Main.cs -pkg:gtk-sharp
$ mono Main.exe

When you run the application, you will see a window as in Figure 8: the button takes up the entire space in the window. Click the button a few times, and you'll see the output on the terminal as shown in Figure 9.

Figure 8. Gtk# window with a button

Figure 9. Terminal output

How does it work?

The Gtk namespace is imported with using Gtk. The basic Gtk# tasks of initialising the toolkit are performed by the Application class. Specifically, there are three static methods of interest.

If you want your application to check whether it can use graphics, use the InitCheck method instead of Init. That way it won't fail horribly and you can fall back to a text interface.

  • Init causes the Gtk# library to be initialized. You won't get very far without doing this.
  • Run causes the flow of control to enter the main event loop.
  • Quit causes the event loop to terminate when control is returned to it.

The creation of the window and its button is a trivial matter: there are more interesting examples in the other labs. What is more relevant here is the hooking up of the event handlers. Every widget (user interface element) in Gtk# is capable of raising a variety of events. Many of these are derived from the basic Widget class, from which all the Gtk# widgets inherit. Typical events include Focused, sent when the widget receives user focus, and DeleteEvent, sent when the widget is deleted.

The event handlers need not be static methods if they need to access an object instance. The only difference is to assign them prefixed by the instance.

When an event is raised, the assigned handlers are invoked. Events can have any number of handlers assigned. Example 2 shows the handler Window_Delete being added for the event DeleteEvent.

Our Window_Delete handler does two things of interest. First, it instructs the main loop to exit when control is returned to it. Secondly, it sends true back as a return value via the args object. This stops any subsequent handlers getting the event.

The handler for the Button is much the same, and is more typical of the general widget event handler. Buttons have some specialized events, of which Clicked is the most useful.

The assignment of the handlers has been shown in full to give some hint as to the underlying implementation. However, it's possible to take a shortcut and write the two lines as follows:

w.DeleteEvent += Window_Delete;
b.Clicked += Button_Clicked;

What about...

An introduction to programming with Gtk# can be found as part of the documenation shipped with Monodoc. Refer to the Mono for Gnome Applications section of the Mono Handbook, available from the Monodoc table of contents. As ever, another excellent source of reference material is the Gtk# API reference itself in Monodoc. You can either install Monodoc from or read its contents online at

To understand more about delegates and events, refer to Chapter 2 of C# Essentials, 2nd Edition by Ben Albahari, Peter Drayton, and Brad Merrill (O'Reilly, 2002). A good introduction to the GTK+ toolkit can be found in the GTK+ 2.0 Tutorial, available at tutorial/. Although specific to the C language implementation of GTK+, the tutorial contains a lot of theory about the toolkit that we will only gloss over in this book.

A document outlining the changes available in C# 2.0 can be found linked from Microsoft's C# website, at

Sponsored by: