Create NSView programatically in Xamarin Studio

2019-03-03 01:01发布

问题:

I am trying to find a solution to this question I asked earlier: Populate SourceList in Xamarin.Mac app

I am currently trying to implement the GetView method of the NSOutlineViewDelegate to see if that may create some text in the OutlineView I have.

But I am stuck at trying to add stuff to the NSView object. When I look at the example OutlineView (the one you get by default when you drag it onto your window), there's a TableCellView for each item. The structure looks like this (header first, then regular item):

Table Cell View
  Static Text - HEADER CELL
    Text Field Cell - HEADER CELL

Table Cell View
  Image View
    Image Cell
  Static Text - Table View Cell
    Text Field Cell - Table View Cell

So far my method looks like this:

public override NSView GetView (NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item)
{
    var navigation = item as Navigation;
    var cell = new NSTableCellView();

    if (navigation.IsHeader) {
    } else {
    }

    return cell;
}

My first guess what that for the header, for example, I create a NSTableHeaderCell and set the StringValue property to navigation.Name. But I have no idea how to then add it as a child to my NSTableViewCell.

Or am I going about this the completely wrong way? I am very new to Mono and Xamarin (have only done C# and Visual Studio using WPF and XAML) and I have never before done programming in Objective-C before (so it took me a while to figure out the weird syntax for methods/classes).

回答1:

You'll see in XCode that the Table Cell View objects have an 'Identifier' that you can set. In my case I have 'HeaderCell' and 'DataCell'.

My code looks like this:

public override NSView GetView(NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item)
{
    if(IsGroupItem(outlineView, item))
    {
        return outlineView.MakeView("HeaderCell", this);
    }

    return outlineView.MakeView("DataCell", this);
}

This will create an appropriate instance of the TableCellView defined in XCode.

In my case, I use Cocoa bindings rather than a data source, so my views get populated with data automatically. This may be an approach you want to investigate because it is much closer to the WPF/XAML way of databinding. However, it has a steep learning curve and is difficult to debug (like WPF/XAML databinding!).

Instead of simply returning the cell, you could access it's subviews and set them up appropriately. Something like:

var dataView = outlineView.MakeView("DataCell", this);
((NSImageView)dataView.Subviews[0]).Image = // assign an image
((NSTextField)dataView.Subviews[1]).StringValue = // assign your text
return dataView;

(Note: I just typed that from the top of my head, it may not work as-is - but hopefully you get the idea)