The only thing I could determine from the CollapsingRecordNode example is that it “primes” the sizes of the contained items by recursively initializing the item widths to 160. It does this in the Initialize method of the embedded CollapsingRecordNodeItemList, which is called from the view after everything is constructed.
I tried the same approach, explicitly seeding the item widths of my embedded GoListGroup objects, but it did not have any effect. As you can see from the screenshot below, the widths of the header, content and collapsible sections are all set to the maximum width of their children and not to the width of their parent.

The other difference here is that I need to inherit the port functionality provided by the GoBoxNode, whereas the CollapsingRecordNode inherits directly from GoNode. Although I checked whether inheriting from GoNode would make a difference, but it did not - same behavior.
Here is the code for the class node. The ComponentNodeTitle and ComponentNodeLabel are simple GoText derivatives.
public class ComponentClassNode : GoBoxNode, IGoCollapsible
{
static Font _titleFont = new Font("Segoe UI", 9f, FontStyle.Regular);
static Font _labelFont = new Font("Segoe UI Light", 8.5f, FontStyle.Regular);
static Font _subLabelFont = new Font("Segoe UI Light", 8f, FontStyle.Italic);</p><p> public ComponentClassNode(string title, string description)
{
this.Selectable = false;
this.Resizable = false;
this.PortBorderMargin = new SizeF(1, 1);
this.LinkPointsSpread = false;
Title = title;
Description = description;
Icon = Resources.Widget32;
Body = new NodeBody(this);
}</p><p> public string Title { get; set; }
public string Description { get; set; }
public Image Icon { get; set; }
public Pen Foreground { get { return Pens.White; } }
public Brush Background { get { return Brushes.Orange; } }
public Font LabelFont { get { return _labelFont; } }
public Font TitleFont { get { return _titleFont; } }
public Font SubLabelFont { get { return _subLabelFont; } }
public override string ToolTipText { get { return Description; } }</p><p> /// <summary>
/// Describes the component fields.
/// </summary>
List<FieldDescriptor> _fields;
public List<FieldDescriptor> Fields
{
get
{
if (_fields == null)
{
_fields = new List<FieldDescriptor>
{
new FieldDescriptor {Title="Title", FieldType="String"},
new FieldDescriptor{Title="Description",FieldType="String"}
};
}
return _fields;
}
}</p><p> /// <summary>
/// Describes the component permissions.
/// </summary>
List<PermissionDescriptor> _permissions;
public List<PermissionDescriptor> Permissions
{
get
{
if (_permissions == null)
{
_permissions = new List<PermissionDescriptor>
{
new PermissionDescriptor{ Title="First Role", Permissions="View,Read"},
new PermissionDescriptor{ Title="Designers", Permissions="View,Read,Design"}
};
}
return _permissions;
}
}</p><p> /// <summary>
/// Defines the node body.
/// </summary>
public class NodeBody : GoListGroup
{
public HeaderPanel Header { get; set; }
public ContentPanel Content { get; set; }
private ComponentNodePanel InnerPanel;</p><p> /// <summary>
/// Base class for all the panels.
/// </summary>
public class ComponentNodePanel : GoListGroup
{
protected ComponentClassNode Node { get; set; }
public ComponentNodePanel(ComponentClassNode node)
{
Node = node;
Selectable = false;
DragsNode = true;
AutoRescales = false;
ResizesRealtime = true;
TopLeftMargin = new SizeF(0, 0);
BottomRightMargin = new SizeF(0, 0);
}</p><p> internal void SetAllItemWidth(float w)
{
foreach (GoObject obj in this)
SetItemWidth(obj, w);
}</p><p> public void SetItemWidth(GoObject obj, float w)
{
ComponentNodePanel panel = obj as ComponentNodePanel;
if (panel != null)
panel.SetAllItemWidth(w);
else
{
if (obj.Resizable)
obj.Width = w;
}
}
}</p><p> /// <summary>
/// Creates a panel with an icon, label and handle.
/// </summary>
public class HeaderPanel : ComponentNodePanel
{
GoImage _icon;
NodeBody _body;
ComponentNodeTitle _label;
ComponentClassNodeHandle _handle;</p><p> public HeaderPanel(NodeBody body, ComponentClassNode node)
: base(node)
{
_body = body;</p><p> Brush = node.Background;
Orientation = Orientation.Horizontal;</p><p> Add(_icon = new GoImage { Image = node.Icon, Selectable = false, Resizable = false, AutoRescales = false });
Add(_label = new ComponentNodeTitle(node.Title, node));
Add(_handle = new ComponentClassNodeHandle(node));</p><p> // notice when the label is changed, so we can layout the children
_label.AddObserver(this);
}</p><p> // trap changes to the label so we can resize the node.
protected override void OnObservedChanged(GoObject observed, int subhint, int oldI, object oldVal, RectangleF oldRect, int newI, object newVal, RectangleF newRect)
{
if (subhint == GoText.ChangedText && observed == _label)
{
SizeF minSize = new SizeF(_body.Width - _handle.Width - _icon.Width, _label.Height);
_label.ComputeResize(_label.Bounds, _label.Location, MiddleRight, minSize, minSize, false);
LayoutChildren(null);
}
}</p><p> public override void LayoutChildren(GoObject childchanged)
{
if (this.Initializing) return;
base.LayoutChildren(childchanged);
if (_label != null)
{
// move the label down from the top
_label.Position = new PointF(_label.Left, _label.Top + (32 - _label.Height) / 2);
}
}
}</p><p> /// <summary>
/// Creates a panel with collapsible sections.
/// </summary>
public class ContentPanel : ComponentNodePanel
{
public ContentPanel(NodeBody body, ComponentClassNode node)
: base(node)
{
Brush = Brushes.White;
Add(new ComponentNodeCollapsingPanel("Fields", node, node.Fields));
Add(new ComponentNodeCollapsingPanel("Permissions", node, node.Permissions));
}
}</p><p> /// <summary>
/// Displays a section header with a collapsible handle.
/// </summary>
public class ComponentNodeSectionHeader : ComponentNodePanel
{
ComponentNodeLabel _label;
GoCollapsibleHandle _handle;</p><p> public ComponentNodeSectionHeader(string title, ComponentClassNode node)
: base(node)
{
Orientation = Orientation.Horizontal;
Add(_handle = new ComponentNodeSectionHandle(node));
Add(_label = new ComponentNodeLabel(title, node));
}</p><p> public override void LayoutChildren(GoObject childchanged)
{
if (this.Initializing) return;
base.LayoutChildren(childchanged);
if (_label != null)
_label.Position = new PointF(_label.Left + 4, _label.Top);
}
}</p><p> /// <summary>
/// A generic collapsing panel.
/// </summary>
public class ComponentNodeCollapsingPanel : ComponentNodePanel, IGoCollapsible
{
GoListGroup _content;
public ComponentNodeCollapsingPanel(string title, ComponentClassNode node, IList items)
: base(node)
{
BorderPen = Pens.Orange;
Add(new ComponentNodeSectionHeader(title, node));
_content = new ComponentNodePanel(node);
foreach (var item in items)
_content.Add(new ComponentNodeSubLabel(item.ToString(), node));
Add(_content);
Collapse();
}</p><p> // IGoCollapsible
public bool Collapsible { get { return true; } set { } }
public void Collapse() { _content.Visible = false; _content.Printable = false; LayoutChildren(null); }
public void Expand() { _content.Visible = true; _content.Printable = true; LayoutChildren(null); }
public bool IsExpanded { get { return _content.Visible; } }
}</p><p> /// <summary>
/// ctor
/// </summary>
public NodeBody(ComponentClassNode node)
{
Resizable = false;
TopLeftMargin = new SizeF(2, 2);
BottomRightMargin = new SizeF(2, 2);
Brush = node.Background;
BorderPen = Pens.Orange;</p><p> Add(InnerPanel = new ComponentNodePanel(node)
{
Selectable = false,
Brush = Brushes.White,
Alignment = MiddleLeft
});</p><p> InnerPanel.Add(Header = new HeaderPanel(this, node));
InnerPanel.Add(Content = new ContentPanel(this, node));
}</p><p> // IGoCollapsible
public bool Collapsible { get { return true; } set { } }
public void Expand() { Content.Visible = true; InnerPanel.LayoutChildren(null); }
public void Collapse() { Content.Visible = false; InnerPanel.LayoutChildren(null); }
public bool IsExpanded { get { return Content.Visible; } }
}</p><p> // IGoCollapsible
public bool Collapsible { get { return true; } set { } }
public void Collapse() { ((NodeBody)Body).Collapse(); }
public void Expand() { ((NodeBody)Body).Expand(); }
public bool IsExpanded { get { return ((NodeBody)Body).IsExpanded; } }
}