Back to Index

Getting an NSTableView to display something

The problem with an NSTableView is that we cannot tell it what to do. NSTableView works like the old joke about Soviet Russia: "In Soviet Russia television watches you". In other words, instead of us calling methods in the NSTableView object, the NSTableView object expects us to provide a data source object with methods for the NSTableView object to call.

Our plan shall be to put an NSTableView in our window and then write a class that acts as its data source, instantiate the class and hope for the best.

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.

3. In the Object Library find an NSTableView control.


Picture 1: We found an NSTableView in the Object Library

4. Drag the NSTableView into the window.


Picture 2: The window with an NSTableView

Note that the NSTableView is embedded in an NSScrollView which we will try to ignore.

5. Try clicking on the actual NSTableView control.


Picture 3: We managed to click on the actual NSTableView control.

6. Find the configuration thingy for the NSTableView control and configure it for one column, with no reordering or resizing.


Picture 4: The NSTableView configuration thingy.

7. Find the button to call the Assistant editor.


Picture 5: Found the Assistant editor button.

8. Configure the Assistant editor to display MainWindow.h and control-drag the NSTableView control into the MainWindow class.


Picture 6: Name the outlet "tblTable".

9. Add a file TableViewDataSource.cs with the following content.

// File TableViewDataSource.cs
using System;
using System.Collections.Generic;
using System.Linq;
using MonoMac.Foundation;
using MonoMac.AppKit;

namespace Test
{
    [Register ("TableViewDataSource")]
    public class TableViewDataSource : NSTableViewDataSource
    {
        public TableViewDataSource ()
        {
        }
       
        // This method will be called by the NSTableView control to learn the number of rows to display.
        [Export ("numberOfRowsInTableView:")]
        public int NumberOfRowsInTableView(NSTableView table)
        {
            Console.WriteLine("numberOfRowsInTableView:");
            // We just return a static 2. We will have two rows.
            return 2;
        }
       
        // This method will be called by the control for each column and each row.
        [Export ("tableView:objectValueForTableColumn:row:")]
        public NSObject ObjectValueForTableColumn(NSTableView table, NSTableColumn col, int row)
        {
            Console.WriteLine("tableView:objectValueForTableColumn:row:");
            switch (row)
            {
            case 0:
                // We will write "Hello" in the first row...
                return new NSString("Hello");
            case 1:
                // ...and "World" in the second.
                return new NSString("World");
                // Note that NSTableView requires an NSString, which we create with new NSString("bla").
            default:
                // We need a default value.
                return null;
            }
        }
    }//class
}//namespace


10. Modify MainWindow.cs to include the following.

    // This method will be called automatically when the main window "wakes up".
    [Export ("awakeFromNib:")]
    public override void AwakeFromNib()
    {
        Console.WriteLine("awakeFromNib:");
        tblTable.DataSource = new TableViewDataSource();
    }
 
MainWindow.cs knows about tblTable. All we have to do to connect our NSTableView control to our data source is to tell tblTable that its data source is a new instance of TableViewDataSource.

11. Run the application and see that "Hello" and "World" are being displayed in the NSTableView.


Picture 7: Result!
 
 
(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 23rd 2012