How to rearrange nodes within subgraph?

My diagram contains 4 MultiTextNodes, a GoGroup with 2 MultiTextNodes, and a GoSubGraph that contains 7 GoGeneralNodes. I have unsuccessfully tried to eliminate the excess spacing within the subgraph (after calling the PerformLayout) by overriding the GoSubGraph.LayoutChildren to reposition the GoGeneralNodes closer to the top.
Please show me how to effectively call the PerformLayout or code to rearrange the nodes within the subgraph. Many Thanks.

Henry,

I’m going to work on some code for you today.

Thanks Jake.

Please also show me how to relink after the GoGroup is collapsed.

Here’s what we sent to Henry:

using System;
using System.Drawing;
using Northwoods.Go;

namespace SubGraphApp {
  [Serializable]
  public class HeaderFooterSubGraph : GoSubGraph {
    public HeaderFooterSubGraph() {
      this.BorderPenColor = Color.Gray;  // instead of none by default

      myHeader = CreateHeader("HEADER");
      this.Add(myHeader);

      myFooter = CreateHeader("FOOTER");
      this.Add(myFooter);

      this.TopLeftMargin = new SizeF(0, myHeader.Height + 5);  // instead of default 4x4
      this.BottomRightMargin = new SizeF(0, myFooter.Height + 5);  // instead of default 4x4

      this.CollapsedTopLeftMargin = new SizeF(0, myHeader.Height);
      this.CollapsedBottomRightMargin = new SizeF(0, myFooter.Height);

      GoRectangle spacer = new GoRectangle();
      spacer.Size = new SizeF(75,1);
      spacer.PenWidth = 0;
      spacer.Selectable = false;
      spacer.Pen = null;
      CollapsedObject = spacer;
    }

    protected override void CopyChildren(GoGroup newgroup, GoCopyDictionary env) {
      base.CopyChildren(newgroup, env);
      HeaderFooterSubGraph newsg = (HeaderFooterSubGraph)newgroup;
      newsg.myHeader = (GoListGroup)env[myHeader];
      newsg.myFooter = (GoListGroup)env[myFooter];
    }

    private static GoListGroup CreateHeader(string label) {
      GoListGroup listgroup = new GoListGroup();
      listgroup.Alignment = GoObject.Middle;
      listgroup.Selectable = false;
      listgroup.PickableBackground = true;    // makes SubGraph draggable by header/footer
      listgroup.BorderPenWidth = 0;
      listgroup.LinePenWidth = 0;
      listgroup.BrushColor = Color.BlueViolet;

      GoRectangle spacer = new GoRectangle();
      spacer.Size = new SizeF(0, 0);
      spacer.PenWidth = 0;
      spacer.Selectable = false;
      spacer.Pen = null;
      listgroup.Add(spacer);

      GoText t1 = new GoText();
      t1.Selectable = false;
      t1.Editable = true;
      t1.Text = label;
      t1.Bold = true;
      t1.TextColor = Color.White;
      t1.TransparentBackground = true;
      listgroup.Add(t1);

      t1 = new GoText();
      t1.Selectable = false;
      t1.Editable = true;
      t1.Text = "line 2";
      t1.TextColor = Color.White;
      t1.TransparentBackground = true;
      listgroup.Add(t1);
      return listgroup;
    }

    public override void LayoutHandle() {
      GoSubGraphHandle h = this.Handle;
      if (h != null && myHeader != null && h.CanView()) {
        h.SetSpotLocation(TopRight, myHeader, TopLeft);
      }
    }

    protected override GoText CreateLabel() {
      return null;
    }

    public override void LayoutChildren(GoObject childchanged) {
      base.LayoutChildren(childchanged);
    }

    protected override PointF ComputeReferencePoint() {
      if (myHeader != null) {
        return new PointF(myHeader.Left, myHeader.Bottom);
      } else return base.ComputeReferencePoint();
    }

    public override void LayoutLabel() {
      if (myHeader != null) {
        RectangleF b = ComputeBorder();
        myHeader.Position = b.Location;
        myHeader[0].Width = b.Width - 4;  // the spacer rectangle
      }
      if (myFooter != null) {
        RectangleF b = ComputeBorder();
        myFooter.SetSpotLocation(GoObject.BottomLeft, new PointF(b.Left, b.Bottom));
        myFooter[0].Width = b.Width - 4;
      }
    }

    public override RectangleF ComputeInsideMargins(GoObject ignore) {
      RectangleF r = base.ComputeInsideMargins(ignore);
      int headerPad = 10; // 
      if (myHeader != null && r.Width < myHeader[1].Width + headerPad) r.Width = myHeader[1].Width + headerPad;
      return r;
    }
    protected override bool ComputeInsideMarginsSkip(GoObject child) {
      if (child == myHeader) return true;
      if (child == myFooter) return true;
      else
        return base.ComputeInsideMarginsSkip(child);
    }

    protected override bool ComputeCollapsedSizeSkip(GoObject child) {
      if (child == myHeader) return true;
      if (child == myFooter) return true;
      else
        return base.ComputeCollapsedSizeSkip(child);
    }

    protected override void CollapseChild(GoObject child, RectangleF sgrect) {
      if (child == myHeader) return;
      if (child == myFooter) return;
      else
        base.CollapseChild(child, sgrect);
    }

    GoListGroup myHeader = null;
    GoListGroup myFooter = null;
  }
}