My favorites | Sign in
Project Logo
                
Search
for
Updated Mar 14, 2007 by jendave.hudson
SimpleTutorial  
An extremely simple Cocoa# tutorial. Simple form with a textbox and a button.

Assumptions

For this tutorial I will assume that you have OS X, Mono 1.1.8.1, Cocoa#, and Apple's Developer Tools installed. I'm also assuming that you're a novice at Apple Tools and using Cocoa#. I just switched from Windows to Apple 2 months ago. I had to figure all of this out the hard way :)

Starting Off

Building The NIB

The first thing to do is create a NIB file for use with the application. A NIB file is so much easier to use than creating the entire window and controls via code.

  1. Go to Macintosh HD/Developer/Applications and run Interface Builder.
  2. Create a new Cocoa Application.
  3. Drag a "NSButton" and "NSTextField" from the controls windows to the empty window that is being displayed.
  4. In the smaller window (normally lower left) that has 5 Segments named Instances, Classes, Images, Sounds, and Nibs click on Classes.
  5. Scroll all the way to your left, Right Click on the "NSObject" and select "SubClass NSObject".
  6. Name the new object "ApplicationController".
  7. Right Click on "ApplicationController" and select "Instantiate ApplicationController". This will make the Instances tab of the window visible. You should now see a blue cube with the name of "ApplicationController".
  8. Click on the Classes tab again, find "ApplicationController", and Right Click on it, select "Add Outlet".
  9. This will make the Info Window visible (if it wasn't already). Add a new outlet named "textBox1", set the type to "NSTextField". Add another outlet named "mainWindow" and set type to "NSWindow". In the same window click on the "Actions" tab and add an action named "buttonClick".
  10. Go back to the Instances tab, hold the Ctrl key down and click on "ApplicationController" and drag to the "NSTextField". After you do this the Info window will appear (if not already visible) and will be on the Outlet's page. Make sure that you highlight the outlet named "textBox1" and then hit "Connect".
  11. Ctrl Click and drag from the "NSButton" to the "ApplicationController" The Info window will appear, if the "buttonClick" action is not highlighted, go ahead and highlight it and then click connect.
  12. Ctrl Click and drag from "File's Owner" to "ApplicationController", connect to the "delegate" Outlet.
  13. Ctrl Click and drag from "ApplicationController" to "Window" instance (located in Instance tab) Assign this to outlet "mainWindow".
  14. Ctrl Click and drag from "Window" to "ApplicationController" and assign this to outlet "delegate".

Actions vs. Outlets

Actions: Actions are like events. Creating an action in a nib will allow you to assign it to any control that has event capabilities. ''Note: You can also assign actions via code (ie "button1.action = buttonClick")''

Actions are connected by Ctrl Clicking/Dragging from the Interface Element to the Controller Object

Outlets: Outlets are a way to tie objects in the GUI to variables in code. If you don't have the outlet tied to anything then you can't use it. It's a way to tell the Code what variable is pointing to what interface element.

Outlets are connected by Ctrl Clicking/Dragging from the Controller Object to the Interface Element

The Code

Main.cs

The main.cs file is the entry point to the app. I split this off from the actual ""ApplicationController"" so that I can keep track of things easily.

using System;
using System.Runtime.InteropServices;
using Apple.Foundation;
using Apple.AppKit;

class MainClass {
	public void Run() {
		Console.WriteLine ("initing: {0:x}", (int)Apple.Foundation.Class.Get("NSBundle"));
		Application.Init();
		Console.WriteLine ("initd");
		Application.LoadNib ("Main.nib");
		Application.Run();
	}
	
	static void Main(string[] args) {
		MainClass main = new MainClass();
		main.Run();
	}
}

The important thing to consider here is the "Application.LoadNib()" line. Make sure it's loading the proper NIB file.

ApplicationController.cs

The applicationcontroller.cs is the main interface handling point. This is where all the GUI elements are connected and defined.

using System;
using System.IO;
using System.Collections;
using Apple.Foundation;
using Apple.AppKit;

[Register("ApplicationController")]
public class ApplicationController : NSObject {
        
	[Connect]
	public NSTextField textBox1;
        
	[Connect]
	public NSWindow mainWindow;

	protected ApplicationController(System.IntPtr a, bool b) : base(a, b){}
        
	//Form.Load Event
	[Export("applicationWillFinishLaunching:")]
	public void FinishLoading(NSNotification aNotification) {
		textBox1.stringValue = "Form Loaded";
	}

	[Export("buttonClick:")]
	public void buttonClick(object sender) {
		textBox1.stringValue = "Button Pushed";
	}
        	
}

Connect/Register

I'm not sure what the technical explanation for this is, but this is the part that connects the variable you define to the object from the nib. You can have interface elements that do not have a local variable in the code, but you cannot connect local variables to non existant interface elements. Doing so will cause the app to crash on launch. For every interface element that you want to be able to access via code, you will need to create a new variable of the proper type and make sure that you use the "Connect" statement above it.

The Register statement above the beginning of the class connects this class to the "ApplicationController" from the NIB.

Export

The export tag is the one that ties local events to the events declared in the NIB. You can assign these events to an interface object a couple of ways. You can Ctrl Click and drag from the interface element to the controller class, or you can define it via code. The NIB method is normally easiest but some interface elements don't like it.

In the above example you can see that I have exported "buttonClick:" to my local buttonClick handler. The "applicationWillFinishLaunching:" event is generated by the (app/main window). Think of it like the FormLoad event in winforms (as far as I can tell).

Helper Files

I create two more files just to kinda make my life easier. I create a makefile and then a command file. I create the command file so that I don't have to keep a terminal window open all the time.

Makefile

all: test

test: Main.cs
	mcs -t:exe -out:SimpleTutorial.exe -pkg:cocoa-sharp *.cs
	rm -rf SimpleTutorial.app
	macpack -m:2 -n:SimpleTutorial -o:. -a:SimpleTutorial.exe -r:/Library/Frameworks/Mono.framework/
Versions/Current/lib/libCocoaSharpGlue.dylib -r:Main.nib

I don't know much about makefiles, but the important parts in this file are anywhere the name "SimpleTutorial" is mentioned. Change this to whatever you want your program to be named. The -pkg option on the mcs command makes sure that it's compiled with the cocoasharp package. MacPack is the tool that creates the app bundles for OS X. Make sure you include any nibs/images/icons/etc as a resource by using the -r option of macpack.

Command File

This will give you a file you can just double click on to run the make file. Create this file in text editor and save it as <something>.command

#!/bin/tcsh
# if launched from the finder, we'll not be in the correct directory.
# get to the directory where this script file lives
cd `dirname $0`

make

Finished

Well, you should now be finished. Double Click on the <somthing>.command file and you should see everything compile successfully. If all went well you should see an OS app icon labeled SimpleTutorial. Double click on it, and you should see a new app running.

If not, or if you find an error, please send an email to binary.god@gmail.com or comment in this wiki page.


Comment by rogerclark, Jul 30, 2007

anus

Comment by rogerclark, Jul 30, 2007

anus shit

Comment by jkordani.mailinglists, Dec 27, 2007

Apparently, the using apple. need to be changed to using Cocoa; ? this further presents this:

ApplicationController?.cs(7,38): error CS0246: The type or namespace name `NSObject' could not be found. Are you missing a using directive or an assembly reference?

Comment by justizin, Dec 29, 2007

This tutorial is inconsistent with the latest Interface Builder for OSX Leopard / Xcode 3.0. The window Step 4 refers to has been completely redesigned and it is not clear how to translate these steps for the new interface. I will gladly update here if I sort it out.

Comment by jacobopolavieja, Jan 10, 2008

Same problem as justizin... Completely redesigned and no clue how to make it through the new interface.

Hope we can get something clarifying soon. Mono on the Mac can be an amazing thing.

Thanks for all the work you do.

Cheers.

Comment by jacobopolavieja, Jan 10, 2008

After a while struggling with it it seems like with the new interface you have to drag and drop a "NSObject" (couldn't find nothing similar to a "SubClass? NSObject") from the controllers folder to the application's items. Then should we use the "Inspector" tool from the "Tools" menu to add the outlets, make the connections and all.

Just a guess for all of you to try as I haven't been able to run it completely due to errors in the code (something about an array declaration)... I will be looking at it when I have more time.

Hope it helps.

Thank you all.

Comment by Mmarsu, Jan 20, 2008

Interface Builder for OSX Leopard / Xcode 3.0 step 7

"Instantiate ApplicationController?"

I don't know how to do this, so event are not connected Runtime error : "Could not connect the action buttonClick: to target of class NSObject"

tip: when you save the nib with Interface builder select nib 2.X since buttonClick: event is performClick: in 3.X

Comment by sjmulder, Jan 22, 2008

To insantiate an object in Interface Builder 3, do the following:

# Find the NSObject item in the Library palette (Command-Shift-L). # Drag it into the nib window, where the other objects reside. # Select the Identity tab in the inspector (Command-Shift-I). It's 'i', the second one from the right. # In the Class field under the Class Identity heading, enter the name of the class. # Optionally, you can set a name for the object in the same pane, using the Name field under the Interface Builder heading.

As far as I know, class definitions are now synchronized automatically. And when Control-dragging, a little black tool window pops up where you can select the outlet or action.

Right (or Option-) click any object to see all its available and used connections.

Comment by sjmulder, Jan 22, 2008

I can't get the markup to do what I want, hope it's clear though.

Comment by c4software, Oct 10, 2008

Hmmm i'm in trouble,

When i try to Compile i get :

ApplicationController?.cs(7,38): error CS0246: The type or namespace name `NSObject' could not be found. Are you missing a using directive or an assembly reference?

Any Idea To solve this problem ?

Comment by c4software, Oct 10, 2008

Hmmm Okay i try a lot of thing and i get an solution :

public class ApplicationController? : NSObject { ...

By public class ApplicationController? : Cocoa.Object { ..

And its seems working

Comment by c4software, Oct 10, 2008

Okay i made some advance. But i block on a little problem. i Can't Click Twice on the same button. if i reclick on a button? Mono generate an error :

System.ArgumentException?: Object type Cocoa.Object cannot be converted to target type: Cocoa.Window

And the Program Exit...

If anyone have an Idea ?


Sign in to add a comment
Hosted by Google Code