Back to Index

Getting the application to quit when the main window closes

The trick here is to create a method that calls Environment.Exit() to quit the application like any other .NET application.

The other trick is to notice that Environment.Exit() does not work when Cocoa objects are alive. But NSApplication.SharedApplication.Terminate(this) works. I don't know how to return an error code that way.

Cocoa, and thus MonoMac, uses "delegates" to allow one object to react when something happens to another object. We will use this concept to call Terminate() when the main window closes.

A Cocoa object has "outlets", which appear to be pointers to other objects. I don't know if this is technically the correct description. It doesn't matter. One of the outlets is the "delegate" which we will set to the object that contains the method that we want called when the window is closed. Hence we have to set the main window's delegate outlet to our object.

We will use the MainWindow class defined in MainWindow.cs as delegate for the main window. I guess that means we are using an object as its own delegate or something like that. It will still work.

To make MainWindow the delegate for the main window and react to the main window closing follow these steps.

1. Double-click MainWindow.xib to open Xcode.

2. In Xcode, find the main window. It's the big thing that looks like a window.

Picture 1: The big thing titled "Window" is the main window.

3. Right-click on the title bar of the window to display the window's outlets.

You will see one outlet called "delegate".

Picture 2: One of the "Outlets" is "delegate".

4. Find the "Object Library" and the blue box in it. The blue box is an object.

Picture 3: The blue box is an object.

5. Drag the blue box to the grey thingy with the icons to the left of the window.

Picture 4: The blue box belongs under the window icon.

6. Make the blue box a "MainWindow" object. Click on the blue box and change its class to "MainWindow".

Picture 5: Update the class name for the blue box.

7. Press the control key and drag from the window title bar into the blue box. Then select the "delegate" option in the menu that appears.

Picture 6: The menu that appears when you control-drag.

Our MainWindow object is now the delegate for the main window. This means it can react to things that happen to the window.

8. Add the following code to MainWindow.cs:

    [Export ("windowWillClose:")]
    public void WindowWillClose(NSNotification notification)
        NSApplication.SharedApplication.Terminate (this);      

The [Export ("windowWillClose:")] statement tells the compiler (presumably the compiler, but maybe some other utility technically does the being told) that the following method declaration is the C# equivalent of the Objective-C method announced. The method can have a different actual name but should be named similarly enough so that we can identify it easily enough. I usually just change the first letter to its upper-case version to conform to C# style.

9. Compile the application, fix all the typos you made, then run it. Try closing the window. The application will quit.

If not, repeat all the steps told here until it does..

(c) Andrew J. Brehm
Feel free to copy/translate/whatever but keep a pointer to the original location in case I find one of my many, many mistakes and update the document.
Zurich, January 22nd 2012