OK, assuming two Diagrams with independent Models, and also assuming that there is a many-to-many relationship between the nodes in one model with the nodes of the other model:
<UserControl x:Class="TwoModels.TwoModels"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:go="http://schemas.nwoods.com/GoXam"
xmlns:local="clr-namespace:TwoModels">
<UserControl.Resources>
<DataTemplate x:Key="NodeTemplate1">
<go:NodePanel Sizing="Auto"
go:Part.SelectionAdorned="True"
go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}">
<go:NodeShape go:NodePanel.Figure="Pentagon"
Fill="LightBlue" Stroke="Black" StrokeThickness="1"
go:Node.PortId="" />
<TextBlock Text="{Binding Path=Data.Key}" Margin="10" />
</go:NodePanel>
</DataTemplate>
<DataTemplate x:Key="NodeTemplate2">
<StackPanel go:Part.SelectionAdorned="True"
go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}">
<Ellipse Fill="LightGreen" Width="30" Height="30"
go:Node.PortId="" />
<TextBlock Text="{Binding Path=Data.Key}" Foreground="Green"
HorizontalAlignment="Center" />
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0"
Text="These nodes only move vertically" />
<TextBlock Grid.Row="0" Grid.Column="1"
Text="These nodes move horizontally when prefixed with the key of a myDiagram1 node" />
<go:Diagram Grid.Row="1" Grid.Column="0"
x:Name="myDiagram1" Padding="10"
BorderBrush="Blue" BorderThickness="1"
HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
NodeTemplate="{StaticResource NodeTemplate1}">
<go:Diagram.DraggingTool>
<local:CustomDraggingTool Tag="{Binding ElementName=myDiagram2}"/>
</go:Diagram.DraggingTool>
</go:Diagram>
<go:Diagram Grid.Row="1" Grid.Column="1"
x:Name="myDiagram2" Padding="10"
BorderBrush="Green" BorderThickness="1"
HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"
NodeTemplate="{StaticResource NodeTemplate2}" />
</Grid>
</UserControl>
[code]using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using Northwoods.GoXam;
using Northwoods.GoXam.Model;
using Northwoods.GoXam.Tool;
namespace TwoModels {
public partial class TwoModels : UserControl {
public TwoModels() {
InitializeComponent();
var model1 = new GraphLinksModel<MyNodeData, String, String, MyLinkData>();
model1.NodesSource = new ObservableCollection<MyNodeData>() {
new MyNodeData() { Key="one", Location=new Point(10, 10) },
new MyNodeData() { Key="two", Location=new Point(110, 10) }
};
myDiagram1.Model = model1;
var model2 = new GraphLinksModel<MyNodeData, String, String, MyLinkData>();
model2.NodesSource = new ObservableCollection<MyNodeData>() {
new MyNodeData() { Key="oneA", Location=new Point(10, 10) },
new MyNodeData() { Key="oneB", Location=new Point(10, 110) },
new MyNodeData() { Key="three", Location=new Point(110, 210) }
};
myDiagram2.Model = model2;
}
}
// this DraggingTool is used by myDiagram1, but modifies the node data in myDiagram2.Model
public class CustomDraggingTool : DraggingTool {
public Diagram OtherDiagram {
get { return this.Tag as Diagram; }
}
// limit movement to be vertical only
protected override Point ComputeMove(Node n, Point newloc, Dictionary<Part, DraggingTool.Info> draggedparts) {
return new Point(n.Location.X, newloc.Y);
}
public override void DoActivate() {
base.DoActivate();
if (this.OtherDiagram != null) this.OtherDiagram.StartTransaction("Diagram1 moves");
}
public override void DoDeactivate() {
base.DoDeactivate();
if (this.OtherDiagram != null) this.OtherDiagram.CommitTransaction("Diagram1 moves");
}
protected override void DragOver(Point pt, bool moving, bool copying) {
base.DragOver(pt, moving, copying);
if (this.OtherDiagram == null) return;
foreach (Part p in this.DraggedParts.Keys) {
var n = p as Node;
if (n == null) continue; // ignore Links
var data = n.Data as MyNodeData;
if (data == null) continue; // not data bound?
foreach (var otherdata in this.OtherDiagram.NodesSource as IEnumerable<MyNodeData>) {
if (otherdata.Key.StartsWith(data.Key)) {
// move related nodes in X direction just as this node is being dragged in the Y direction
otherdata.Location = new Point(data.Location.Y, otherdata.Location.Y);
}
}
}
}
}
public class MyNodeData : GraphLinksModelNodeData {
}
public class MyLinkData : GraphLinksModelLinkData<String, String> {
}
}[/code]