Group layouts for virtualizing diagrams

I've seen the recently updated virtualizing diagram example and want to use it for my code. I made minor modifications to the example to address the situation that I have. I'm using GoXam for Silverlight version 1.3.5.4 My diagram is essentially a tree diagram but, sporadically, there are cases where I want to use a different layout. When such a case comes up, I add an extra node that I declare is a subgraph and give the appropriate nodes a subgraph key. I added a GroupTemplate that uses a grid layout for these nodes.

I modified the virtualizing sample to generate a nonvirtual diagram that works like my code. Here's a capture (the GroupTemplate has been given a red background):
When I apply this to the virtualizing example, the grid layout for the group template isn't applied. Here's the detail of a particular group. The virtualization produces this:
However, I expected it to produce this:
I'm wondering what I need to do.
--------------------------------------------------
Below is the xaml for my non-virtualizing diagram. To update the virtualizing example, add the two new resources, add the GroupTemplate attribute to the diagram and add the Comparer attribute to the diagram's tree layout.
<UserControl x:Class="VirtualizingExample.NonVirtualGroups"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:go=”http://schmas.nwoods.com/GoXam”
xmlns:golayout="clr-namespace:Northwoods.GoXam.Layout;assembly=Northwoods.GoSilverlight"
xmlns:local="clr-namespace:VirtualizingExample">
<go:NodePanel Sizing="Fixed"
go:Part.SelectionAdorned="True"
go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}"
go:Node.LocationSpot="Center">
<go:NodeShape go:NodePanel.Figure="RoundedRectangle"
Width="{Binding Path=Data.Width}"
Height="{Binding Path=Data.Height}"
Fill="{Binding Path=Data.Color}" Stroke="Black"
StrokeThickness="1" />
<TextBlock Text="{Binding Path=Data.Key}" Foreground="Black"
HorizontalAlignment="Center" VerticalAlignment="Center" />
<Border go:Node.LocationElementName="GroupPanel"
BorderBrush="Red" BorderThickness="3"
Background="Red" Opacity="0.3"
go:Group.IsSubGraphExpanded="True">
<golayout:GridLayout
Sorting="Descending"
CellSize="100,0"
Conditions="Standard VisibleChanged"
Comparer="{StaticResource NodeComparer}"/>
<go:Diagram Grid.Row="1" x:Name="myDiagram" Padding="10"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
InitialStretch="UniformToFill"
NodeTemplate="{StaticResource NodeTemplate}"
GroupTemplate="{StaticResource GroupTemplate}">
<go:TreeLayout NodeSpacing="10"
Comparer="{StaticResource NodeComparer}"/>
My only other modificatons were to the methods GenerateNodes and GenerateLinks; this was done to produce an example that demonstrates my issue. I also added a comparer class.
These were all written so that the same code can generate both the virtual and nonvirtual diagrams.
public void GenerateNodes(IList nodes, bool bVirtual = true)
{
int numNodes = bVirtual ? 9999 : 100;
int groupsPerHundred = 10;
Random rand = new Random();
for (int i = 0; i < numNodes; i++)
{
var d = new NodeData()
{
Key = i.ToString(),
// Width and Height could be set based on the Category
// or other information available when creating this node data object
// assume VirtualTreeLayout will assign the Location
Color = String.Format("#{0:X}{1:X}{2:X}", 120 + rand.Next(100),
120 + rand.Next(100), 120 + rand.Next(100))
};
if (i == 0 || bVirtual)
d.Location = new Point(0, 0); // locate root node
if (rand.Next(groupsPerHundred) == 0 && i != 0)
{
// create a group node to contain this node
var g = new NodeData()
{
Key = d.Key + "-G",
Location = new Point(0, 0),
IsSubGraph = true
};
nodes.Add(g);
d.SubGraphKey = g.Key;
}
nodes.Add(d);
}
}
public void GenerateLinks(IList nodes, IList links)
{
int maxLinks = 3;
var available = new HashSet(nodes);
Random rand = new Random();
foreach (NodeData next in nodes)
{
available.Remove(next);
if (next.IsSubGraph)
continue;
int children = rand.Next(maxLinks) + 1;
for (int i = 0; i < children; i++)
{
NodeData to = available.FirstOrDefault(n => (!n.IsSubGraph));
if (to == null)
return;
available.Remove(to);
if (next.SubGraphKey != null && i == children - 1)
to.SubGraphKey = next.SubGraphKey;
links.Add(new LinkData() { From = next.Key, To = to.Key });
}
}
}
// This class provides a comparator of nodes
public class NodeComparer : IComparer, IComparer
{
#region IComparer Members - for nonvirtualizing diagram
public int Compare(Node x, Node y)
{
return Compare(x.Data as NodeData, y.Data as NodeData);
}
#endregion
#region IComparer Members - for virtualizing diagram
public int Compare(TreeVertex x, TreeVertex y)
{
var xVertex = x as VirtualizingTreeVertex;
var yVertex = y as VirtualizingTreeVertex;
if (xVertex == null || yVertex == null)
return 0;
return Compare (xVertex.Data, yVertex.Data);
}
#endregion
private int Compare(NodeData xData, NodeData yData)
{
if (xData == null || yData == null)
return 0;
int xInt;
int yInt;
if (!int.TryParse(xData.Key, out xInt) || !int.TryParse(yData.Key, out yInt))
return 0;
if (xInt == yInt)
return 0;
return xInt < yInt ? 1 : -1;
}
}

The VirtualizingTreeNetwork class does not know about your grouped data. You need to customize it to understand that the group member nodes and links should not be laid out by the VirtualizingTreeLayout.

And the VirtualizingTreeVertex class needs to know the size of the Group nodes given the data that represents a group.

Remember that the whole point of “virtualizing” is that there are no Nodes or Groups or Links at the time the layout is performed. (Well, the root Nodes do exist, if I remember correctly.)