I am trying to figure out MonoMac with Xcode 4 and most things appear to work. However, I cannot figure out how to get windowWillClose: to work.
I added
[Export ("windowWillClose:")]
void windowWillClose(NSNotification notification)
{
Environment.Exit(0);
}
to MainWindow.cs and made MainWindow a delegate for the window. (I tried making MainWindowController the delegate but that simply didn't work.)
However, when I close the window, the delegate method doesn't get called.
What am I overlooking?
With pictures: http://www.netneurotic.net/Mono/MonoMac-windowWillClose.html
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.
Double-click MainWindow.xib to open Xcode.
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.
You will see one outlet called "delegate".
Picture 2: One of the "Outlets" is "delegate".
Picture 3: The blue box is an object.
Picture 4: The blue box belongs under the window icon.
Picture 5: Update the class name for the blue box.
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.
Add the following code to MainWindow.cs:
[Export("windowWillClose:")] public void WindowWillClose(NSNotification notification) { Console.WriteLine("windowWillClose:"); 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.
If not, repeat all the steps told here until it does.
You mentioned that, you made the MainWindowController
as delegate I would suggest that, create separate/inner class that inherits from NSWindowDelegate
, override the WillClose (NSNotification notification)
method and set it as Window Delegate. Job is done.
Code:
class MyDelegate:NSWindowDelegate
{
public override void WillClose (NSNotification notification)
{
}
}
In AwakeFromNib method add this:
Window.Delegate = new MyDelegate();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.