I am using GoXam for Silverlight v2.0.2.5.
My data template for nodes has a “From” port on the outermost stackpanel and a “To” port that is inside the stackpanel on a border control.
<DataTemplate x:Key="nodeTemplate1">
<StackPanel Orientation="Vertical"
go:Part.SelectionAdorned="True"
go:Part.SelectionElementName="VisualNode"
go:Part.LayoutId="Gate"
go:Node.PortId="From"
go:Node.FromSpot="BottomCenter"
MouseLeftButtonDown="Node_MouseLeftButtonDown"
>
<Rectangle Height="28" Stroke="BlanchedAlmond"></Rectangle>
<Border Height="40" Width="40" BorderBrush="Black" Background="{Binding Path=Data.Color}" Opacity="50" x:Name="VisualNode" go:Node.PortId="To" go:Node.ToSpot="TopCenter">
<TextBlock Text="{Binding Path=Data.Key}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</StackPanel>
</DataTemplate>
Most of the time the links correctly go to the “To” port. But sometimes the links go to the top of the node.
I was able to reproduce this by modifying the TreeLayout sample. One change I made is that if you double click on a node it will insert a child. In this case I rapidly clicked on Node16 many, many times and produced the following that shows the problem. Note the links in the lower right going into Node72 - Node76.
Here’s the code:
MainPage.xaml
<UserControl.Resources>
<local:SimpleComparer x:Key="theSimpleComparer" />
<!--<DataTemplate x:Key="nodeTemplate1">
<StackPanel go:Part.SelectionAdorned="True" go:Part.SelectionElementName="ellipse">
<Ellipse x:Name="ellipse" Fill="{Binding Path=Data.Color}" Stroke="Black"
Width="40" Height="40" go:Node.PortId="" />
<TextBlock Text="{Binding Path=Data.Key}" HorizontalAlignment="Center" />
</StackPanel>
</DataTemplate>-->
<DataTemplate x:Key="nodeTemplate1">
<StackPanel Orientation="Vertical"
go:Part.SelectionAdorned="True"
go:Part.SelectionElementName="VisualNode"
go:Part.LayoutId="Gate"
go:Node.PortId="From"
go:Node.FromSpot="BottomCenter"
MouseLeftButtonDown="Node_MouseLeftButtonDown"
>
<Rectangle Height="28" Stroke="BlanchedAlmond"></Rectangle>
<Border Height="40" Width="40" BorderBrush="Black" Background="{Binding Path=Data.Color}" Opacity="50" x:Name="VisualNode" go:Node.PortId="To" go:Node.ToSpot="TopCenter">
<TextBlock Text="{Binding Path=Data.Key}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="linkTemplate1">
<go:LinkPanel>
<go:Link.Route>
<go:Route Routing="Orthogonal" Curve="None" Corner="5" />
</go:Link.Route>
<go:LinkShape Stroke="Black" StrokeThickness="1" />
<Path Fill="Black" go:LinkPanel.ToArrow="Standard" />
</go:LinkPanel>
</DataTemplate>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="4*" />
</Grid.RowDefinitions>
<Border Grid.Row="0" Background="LightGray" Padding="2">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Grid.Column="0" VerticalAlignment="Stretch"
Background="AliceBlue" Margin="1" Padding="1"
BorderBrush="Gray" BorderThickness="2" CornerRadius="2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
<StackPanel>
<TextBlock Text="TreeStyle:" FontWeight="Bold" />
<Grid x:Name="TreeStyleRadioButtonGroup" Tag="LastParents">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<RadioButton Grid.Row="0"
Content="Layered" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="1"
Content="LastParents" Checked="RadioButton_Checked" IsChecked="True" />
<RadioButton Grid.Row="2"
Content="Alternating" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="3"
Content="RootOnly" Checked="RadioButton_Checked" />
</Grid>
<TextBlock Text="New Tree:" FontWeight="Bold" Margin="0 5 0 0" />
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="MinNodes: " />
<TextBox Text="20" x:Name="txtMinNodes" MaxLength="3" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="MaxNodes: " />
<TextBox Text="50" x:Name="txtMaxNodes" MaxLength="3" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="MinChildren: " />
<TextBox Text="3" x:Name="txtMinLinks" MaxLength="2" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="MaxChildren: " />
<TextBox Text="5" x:Name="txtMaxLinks" MaxLength="2" />
</StackPanel>
<Button Content="Generate Tree" Click="GenerateTree_Click" />
</StackPanel>
</ScrollViewer>
</Grid>
</Border>
<Border Grid.Column="1" VerticalAlignment="Stretch"
Background="AliceBlue" Margin="1" Padding="1"
BorderBrush="Gray" BorderThickness="2" CornerRadius="2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Text="Tree Layout Properties" FontWeight="Bold" />
<ScrollViewer Grid.Row="1">
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Angle: "
VerticalAlignment="Center" />
<TextBox x:Name="AngleTextBox" Text="90" />
<TextBlock Text=" (0: right, 90: down, 180: left, 270: up)"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Alignment: "
VerticalAlignment="Center" />
<Grid x:Name="AlignmentRadioButtonGroup" Tag="CenterChildren">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<RadioButton Grid.Row="0" Grid.Column="0"
Content="CenterChildren" Checked="RadioButton_Checked" IsChecked="True" />
<RadioButton Grid.Row="0" Grid.Column="1"
Content="CenterSubtrees" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="1" Grid.Column="0"
Content="Start" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="1" Grid.Column="1"
Content="End" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="2" Grid.Column="0"
Content="Bus" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="2" Grid.Column="1"
Content="TopLeftBus" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="3" Grid.Column="0"
Content="BottomRightBus" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="3" Grid.Column="1"
Content="BusBranching" Checked="RadioButton_Checked" />
</Grid>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="NodeSpacing: "
VerticalAlignment="Center" />
<TextBox x:Name="NodeSpacingTextBox" Text="20" />
<TextBlock Text=" (negative causes overlaps)"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="NodeIndent: "
VerticalAlignment="Center" />
<TextBox x:Name="NodeIndentTextBox" Text="0" />
<TextBlock Text=" (when Start or End; >= zero)"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="NodeIndentPastParent: "
VerticalAlignment="Center" />
<TextBox x:Name="NodeIndentPastParentTextBox" Text="0" />
<TextBlock Text=" (fraction; 0-1)"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="LayerSpacing: "
VerticalAlignment="Center" />
<TextBox x:Name="LayerSpacingTextBox" Text="50" />
<TextBlock Text=" (negative causes overlaps)"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="LayerSpacingParentOverlap: "
VerticalAlignment="Center" />
<TextBox x:Name="LayerSpacingParentOverlapTextBox" Text="0" />
<TextBlock Text=" (fraction; 0-1)"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Sorting: "
VerticalAlignment="Center" />
<Grid x:Name="SortingRadioButtonGroup" Tag="Ascending">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<RadioButton Grid.Row="0" Grid.Column="0"
Content="Forward" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="0" Grid.Column="1"
Content="Reverse" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="1" Grid.Column="0"
Content="Ascending" Checked="RadioButton_Checked" IsChecked="True" />
<RadioButton Grid.Row="1" Grid.Column="1"
Content="Descending" Checked="RadioButton_Checked" />
</Grid>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Compaction: "
VerticalAlignment="Center" />
<StackPanel x:Name="CompactionRadioButtonGroup" Tag="Block"
Orientation="Horizontal">
<RadioButton Content="Block" Checked="RadioButton_Checked" IsChecked="True" />
<RadioButton Content="None" Checked="RadioButton_Checked" />
</StackPanel>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="BreadthLimit: "
VerticalAlignment="Center" />
<TextBox x:Name="BreadthLimitTextBox" Text="0" />
<TextBlock Text=" (zero means no limit)"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="RowSpacing: "
VerticalAlignment="Center" />
<TextBox x:Name="RowSpacingTextBox" Text="25" />
<TextBlock Text=" (negative causes overlaps)"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="RowIndent: "
VerticalAlignment="Center" />
<TextBox x:Name="RowIndentTextBox" Text="10" />
<TextBlock Text=" (>= zero)"
VerticalAlignment="Center" />
</StackPanel>
</StackPanel>
</ScrollViewer>
</Grid>
</Border>
<Border Grid.Column="2" VerticalAlignment="Stretch"
Background="AliceBlue" Margin="1" Padding="1"
BorderBrush="Gray" BorderThickness="2" CornerRadius="2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
Text="Alternate Layout Properties" FontWeight="Bold" />
<ScrollViewer Grid.Row="1">
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Angle: "
VerticalAlignment="Center" />
<TextBox x:Name="AlternateAngleTextBox" Text="90" />
<TextBlock Text=" (0: right, 90: down, 180: left, 270: up)"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Alignment: "
VerticalAlignment="Center" />
<Grid x:Name="AlternateAlignmentRadioButtonGroup" Tag="CenterChildren">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<RadioButton Grid.Row="0" Grid.Column="0"
Content="CenterChildren" Checked="RadioButton_Checked" IsChecked="True" />
<RadioButton Grid.Row="0" Grid.Column="1"
Content="CenterSubtrees" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="1" Grid.Column="0"
Content="Start" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="1" Grid.Column="1"
Content="End" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="2" Grid.Column="0"
Content="Bus" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="2" Grid.Column="1"
Content="TopLeftBus" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="3" Grid.Column="0"
Content="BottomRightBus" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="3" Grid.Column="1"
Content="BusBranching" Checked="RadioButton_Checked" />
</Grid>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="NodeSpacing: "
VerticalAlignment="Center" />
<TextBox x:Name="AlternateNodeSpacingTextBox" Text="20" />
<TextBlock Text=" (negative causes overlaps)"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="NodeIndent: "
VerticalAlignment="Center" />
<TextBox x:Name="AlternateNodeIndentTextBox" Text="0" />
<TextBlock Text=" (when Start or End; >= zero)"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="NodeIndentPastParent: "
VerticalAlignment="Center" />
<TextBox x:Name="AlternateNodeIndentPastParentTextBox" Text="0" />
<TextBlock Text=" (fraction; 0-1)"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="LayerSpacing: "
VerticalAlignment="Center" />
<TextBox x:Name="AlternateLayerSpacingTextBox" Text="50" />
<TextBlock Text=" (negative causes overlaps)"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="LayerSpacingParentOverlap: "
VerticalAlignment="Center" />
<TextBox x:Name="AlternateLayerSpacingParentOverlapTextBox" Text="0" />
<TextBlock Text=" (fraction; 0-1)"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Sorting: "
VerticalAlignment="Center" />
<Grid x:Name="AlternateSortingRadioButtonGroup" Tag="Ascending">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<RadioButton Grid.Row="0" Grid.Column="0"
Content="Forward" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="0" Grid.Column="1"
Content="Reverse" Checked="RadioButton_Checked" />
<RadioButton Grid.Row="1" Grid.Column="0"
Content="Ascending" Checked="RadioButton_Checked" IsChecked="True" />
<RadioButton Grid.Row="1" Grid.Column="1"
Content="Descending" Checked="RadioButton_Checked" />
</Grid>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Compaction: "
VerticalAlignment="Center" />
<StackPanel x:Name="AlternateCompactionRadioButtonGroup" Tag="Block"
Orientation="Horizontal">
<RadioButton Content="Block" Checked="RadioButton_Checked" IsChecked="True" />
<RadioButton Content="None" Checked="RadioButton_Checked" />
</StackPanel>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="BreadthLimit: "
VerticalAlignment="Center" />
<TextBox x:Name="AlternateBreadthLimitTextBox" Text="0" />
<TextBlock Text=" (zero means no limit)"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="RowSpacing: "
VerticalAlignment="Center" />
<TextBox x:Name="AlternateRowSpacingTextBox" Text="25" />
<TextBlock Text=" (negative causes overlaps)"
VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="RowIndent: "
VerticalAlignment="Center" />
<TextBox x:Name="AlternateRowIndentTextBox" Text="10" />
<TextBlock Text=" (>= zero)"
VerticalAlignment="Center" />
</StackPanel>
</StackPanel>
</ScrollViewer>
</Grid>
</Border>
</Grid>
</Border>
<controls:GridSplitter Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Center" Height="5" />
<go:Diagram x:Name="myDiagram" Grid.Row="2"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
NodeTemplate="{StaticResource nodeTemplate1}"
LinkTemplate="{StaticResource linkTemplate1}">
<go:Diagram.Layout>
<go:TreeLayout
Id="Gate"
Sorting="Ascending"
Angle="90"
Conditions="None"
Comparer="{StaticResource theSimpleComparer}"/>
</go:Diagram.Layout>
</go:Diagram>
</Grid>
MainPage.xaml.cs
/* Copyright © Northwoods Software Corporation, 2008-2013. All Rights Reserved. */
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using Northwoods.GoXam;
using Northwoods.GoXam.Layout;
using Northwoods.GoXam.Model;
namespace GoSilverlightTreeTest2
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
myDiagram.Model = new GraphLinksModel<SimpleData, String, String, LinkData>();
myDiagram.Model.Modifiable = true;
GenerateTree_Click(null, null);
}
Random rand = new Random();
// Takes the random collection of nodes and creates a random tree with them.
// Respects the minimum and maximum number of links from each node.
// (The minimum can be disregarded if we run out of nodes to link to)
private void GenerateLinks()
{
LinksSource = new ObservableCollection<LinkData>();
if (NodesSource.Count == 0) return;
int minLinks, maxLinks;
if (!int.TryParse(txtMinLinks.Text, out minLinks))
minLinks = 1;
if (!int.TryParse(txtMaxLinks.Text, out maxLinks) || minLinks > maxLinks)
maxLinks = minLinks;
List<SimpleData> available = NodesSource.ToList<SimpleData>();
foreach (SimpleData next in NodesSource)
{
available.Remove(next);
int children = rand.Next(minLinks, maxLinks + 1);
for (int i = 1; i <= children; i++)
{
if (available.Count == 0) break;
SimpleData to = available[0];
available.Remove(to);
LinksSource.Add(new LinkData() { From = next.Key, FromPort = "From", To = to.Key, ToPort = "To" });
}
}
}
// Creates a collection of randomly colored nodes.
// Respects the maximum and minimum number of nodes.
private void GenerateNodes()
{
NodesSource = new ObservableCollection<SimpleData>();
int minNodes, maxNodes;
if (!int.TryParse(txtMinNodes.Text, out minNodes))
minNodes = 0;
if (!int.TryParse(txtMaxNodes.Text, out maxNodes) || minNodes > maxNodes)
maxNodes = minNodes;
int numberOfNodes = rand.Next(minNodes, maxNodes + 1);
for (NextNodeKey = 0; NextNodeKey < numberOfNodes; )
{
NodesSource.Add(new SimpleData()
{
Key = "Node" + NextNodeKey++.ToString(),
Color = String.Format("#{0:X}{1:X}{2:X}", 120 + rand.Next(100), 120 + rand.Next(100), 120 + rand.Next(100))
});
}
// Randomize the nodes a little:
for (int i = 0; i < NodesSource.Count; i++)
{
int swap = rand.Next(0, NodesSource.Count);
SimpleData temp = NodesSource[swap];
NodesSource[swap] = NodesSource<em>;
NodesSource<em> = temp;
}
}
private ObservableCollection<SimpleData> NodesSource;
private ObservableCollection<LinkData> LinksSource;
private int NextNodeKey;
// Generates a random tree respecting MinNodes/MaxNodes/MinLinks/MaxLinks
private void GenerateTree_Click(object sender, RoutedEventArgs e)
{
GenerateNodes();
GenerateLinks();
myDiagram.Model.NodesSource = NodesSource;
var lmodel = myDiagram.Model as GraphLinksModel<SimpleData, String, String, LinkData>;
lmodel.LinksSource = LinksSource;
myDiagram.LayoutDiagram();
}
// When a RadioButton becomes checked, set the Tag of the button container to the button's content (string)
// For internationalization, this should use RadioButton.Tag to hold the value, not the RadioButton.Content
private void RadioButton_Checked(object sender, RoutedEventArgs e)
{
RadioButton rb = sender as RadioButton;
if (rb != null)
{
FrameworkElement group = VisualTreeHelper.GetParent(rb) as FrameworkElement;
if (group != null)
{
group.Tag = rb.Content;
}
}
}
private void Node_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// See if they clicked on a node
var node = Part.FindAncestor<Node>(sender as UIElement);
if (node == null)
return;
var nodeData = node.Data as SimpleData;
if (nodeData == null)
return;
e.Handled = true;
if (DiagramPanel.IsDoubleClick(e) || e.ClickCount > 1)
{
myDiagram.StartTransaction("AddNode");
// Add the child node
var newNode = new SimpleData()
{
Key = "Node" + NextNodeKey++.ToString(),
Color = String.Format("#{0:X}{1:X}{2:X}", 120 + rand.Next(100), 120 + rand.Next(100), 120 + rand.Next(100))
};
NodesSource.Add(newNode);
// Add the link
LinksSource.Add(new LinkData() { From = nodeData.Key, FromPort = "From", To = newNode.Key, ToPort = "To" });
myDiagram.CommitTransaction("AddNode");
myDiagram.LayoutDiagram();
}
else
{
// Select the node
myDiagram.SelectedParts.Clear();
node.IsSelected = true;
}
}
}
// Compare vertexes by comparing the suffix of each node data key,
// treated as integer values rather than as strings.
public class SimpleComparer : IComparer<TreeVertex>
{
public int Compare(TreeVertex x, TreeVertex y)
{
SimpleData a = x.Node.Data as SimpleData;
SimpleData b = y.Node.Data as SimpleData;
int num1 = int.Parse(a.Key.Replace("Node", ""));
int num2 = int.Parse(b.Key.Replace("Node", ""));
return num1.CompareTo(num2);
}
}
// add some properties for each node data
public class SimpleData : GraphLinksModelNodeData<String>
{
public String Color
{
get { return _Color; }
set { if (_Color != value) { String old = _Color; _Color = value; RaisePropertyChanged("Color", old, value); } }
}
private String _Color = "White";
}
// no additional properties are needed for link data
public class LinkData : Northwoods.GoXam.Model.GraphLinksModelLinkData<String, String> { }
}