Hi all I'm at the point of having nearly torn all my hair out. This really shouldn't be that hard.
I've PROGRAMATICALLY created an NSTableView with columns and NSTextFields - I've deliberately kept it to text for now to avoid any weird issues with graphics.
The table view is created from an interface as basically I need to pass in one of about a dozen possible interfaces and have it display the table described by that interface. This is all working bar the table isn't auto laying out at all and text in one field bleeds into the next. At one point during my time when I was working on printing I did manage to get it truncating and showing ellipsis at the end but I've tried and tried and couldn't get back to that.
So I basically have a NSTableView with a bunch of columns the controllers.view gets set from SetupTableView and cells created in the Source Class by calls to GetViewforItem.
I think it has something to do with auto layout settings/constraints/resizing masks etc etc etc etc etc. However I'm at my wits end trying to do what should be the basic default - get the view to auto layout.
NSScrollView SetupTableView()
{
_tableView = new NSTableView
{
Identifier = Title,
RowSizeStyle = NSTableViewRowSizeStyle.Default,
Enabled = true,
UsesAlternatingRowBackgroundColors = true,
AutoresizesSubviews = true,
ColumnAutoresizingStyle = NSTableViewColumnAutoresizingStyle.Sequential,
WantsLayer = true,
Layer = NewLayer(),
Bounds = new CGRect(0, 0, 0, 0),
AutoresizingMask = NSViewResizingMask.HeightSizable | NSViewResizingMask.WidthSizable,
AllowsMultipleSelection = false,
AllowsColumnResizing = true,
AllowsColumnSelection = false,
AllowsColumnReordering = false,
AutosaveName = Title,
AutosaveTableColumns = true,
TranslatesAutoresizingMaskIntoConstraints = false,
Target = Self,
DoubleAction = new ObjCRuntime.Selector("ViewDetailsSelector"),
Action = new ObjCRuntime.Selector("SetRootPersonSelector:")
};
var properties = GetGenericType().GetProperties();
foreach (var property in properties)
{
float width = 100;
string columnTitle = property.Name;
ColumnDetail[] columnDetail = property.GetCustomAttributes(typeof(ColumnDetail), false) as ColumnDetail[];
if (columnDetail?.Length == 1)
{
columnTitle = columnDetail[0].ColumnName;
width = columnDetail[0].ColumnWidth;
}
var tableColumn = new NSTableColumn
{
Identifier = property.Name,
MinWidth = width,
Editable = false,
Hidden = false,
Title = columnTitle,
SortDescriptorPrototype = new NSSortDescriptor(property.Name, true),
};
view.AddColumn(tableColumn);
}
if (info.IsOperatingSystemAtLeastVersion(new NSOperatingSystemVersion(10, 13, 0)))
_tableView.UsesAutomaticRowHeights = true; // only available in OSX 13 and above
var scrollView = new NSScrollView
{
DocumentView = _tableView,
HasVerticalScroller = true,
HasHorizontalScroller = true,
AutohidesScrollers = true,
WantsLayer = true,
Layer = NewLayer(),
Bounds = new CGRect(0, 0, 0, 0)
};
return scrollView;
}`
In the source class is this
public override NSView GetViewForItem(NSTableView tableView, NSTableColumn tableColumn, nint row)
{
var index = Array.IndexOf(_fieldNames, tableColumn.Identifier);
if (index < 0 || index > _properties.Length)
return null;
var property = _properties[index];
NSTextAlignment alignment = NSTextAlignment.Left;
ColumnDetail[] x = property.GetCustomAttributes(typeof(ColumnDetail), false) as ColumnDetail[];
if (x?.Length == 1)
alignment = x[0].Alignment;
if (!(tableView.MakeView(CellIdentifier, this) is NSTextField view))
{
view = new NSTextField
{
Identifier = CellIdentifier,
BackgroundColor = NSColor.Clear,
LineBreakMode = NSLineBreakMode.TruncatingTail,
Bordered = false,
Selectable = false,
Editable = false,
Alignment = alignment,
TranslatesAutoresizingMaskIntoConstraints = false,
AutoresizingMask = NSViewResizingMask.HeightSizable | NSViewResizingMask.WidthSizable
};
if (tableView.AutosaveName == "PrintView")
view.Font = NSFont.SystemFontOfSize(8);
}
// Setup view based on the column selected
if (row >= 0)
{
var item = _bindingList[(int)row];
var propertyValue = _properties[index].GetValue(item);
view.StringValue = propertyValue == null ? string.Empty : propertyValue.ToString();
}
else
view.StringValue = string.Empty;
return view;
}