RelativeSource Binding Issue

I am using Version 1.1.3.3, GoXam. I have a binding issue that shows up at times when adding a node to the diagram. In the sample below, the RelativeSource binding works on teh initially added node, but does not work on an added node (of the same type and DataTemplate). Below is a small sample that demonstrates the issue. The initial node added binds correctly, press the ‘Add’ button and the added node does not find the relativesource binding. Please advise.

[code]
<Window x:Class="GoXamBrowser.MainWindow"
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:GoXamBrowser"
Title="MainWindow" Height="350" Width="525">



<Border Name="NodeBorder" BorderBrush="Gray" BorderThickness="2" CornerRadius="3" Background="Aqua"
go:Part.SelectionAdorned="True" go:Part.Resizable="True"
go:Node.FromSpot="AllSides" go:Node.ToSpot="AllSides"
go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}">












<go:LinkShape x:Name="Path" StrokeThickness="2"
Stroke="{Binding Path=Part.IsSelected,
Converter={StaticResource theSelectedBrushConverter}}" />
<Polygon Fill="Black" Points="8 4 0 8 2 4 0 0" go:LinkPanel.Index="-1"
go:LinkPanel.Alignment="1 0.5" go:LinkPanel.Orientation="Along" />












<go:Diagram Grid.Row="1" x:Name="myDiagram"
Padding="10"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
NodeTemplate="{StaticResource FieldTemplate}"
LinkTemplate="{StaticResource ReferenceTemplate}" />


[/code]
Code-behind for page:
[code]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Northwoods.GoXam;
using Northwoods.GoXam.Model;
namespace GoXamBrowser
{
///
/// Interaction logic for MainWindow.xaml
///

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainModel("Sample");
var model = new GraphLinksModel();
model.Modifiable = true; // let the model be modified
model.NodeKeyPath = "Key"; // use the GraphModelNodeData.Key property
this.myDiagram.Model = model;
this.myDiagram.Layout = new Northwoods.GoXam.Layout.LayeredDigraphLayout();
myDiagram.StartTransaction("Init");
myDiagram.Model.AddNode(new SampleNode("First", "first node"));
myDiagram.CommitTransaction("Init");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
myDiagram.StartTransaction("Add");
myDiagram.Model.AddNode(new SampleNode(txtName.Text, "new node"));
myDiagram.CommitTransaction("Add");
}
}
public class MainModel
{
public MainModel(string label) { SharedLabel = label; }
public string SharedLabel { get; set; }
}
public class SampleNode : GraphLinksModelNodeData
{
public SampleNode(string name, string comment) : base()
{
Name = name;
Comment = comment;
}
public string Name { get; set; }
public string Comment { get; set; }
}
public class SampleLink : GraphLinksModelLinkData
{
}
}
[/code]

In data-binding, RelativeSource with Mode=FindAncestor looks up the visual tree, right? Perhaps the binding is being evaluated too soon, before that TextBlock is part of the Diagram’s visual tree.

You could try this instead:
Text="{Binding Path=Node.Diagram.DataContext.SharedLabel}"

I hope that works for you.

Your exact syntax did not work, but I can fix the sample I gave, but…

I can make it work (for the sample I gave) if I swap the following XAML:
[code]
<TextBlock Text="{Binding Path=Diagram.DataContext.SharedLabel, RelativeSource={RelativeSource TemplatedParent}}"/>
[/code]
But my issue is that since my real application is using a nested ListView and nested , the context of the TemplatedParent in my app is NOT the go:Node, so I cannot get to the node's Diagram without walking the tree with Mode=FindAncestor.
Any other suggestions to find the Diagram's (or Page's) DataContext under this situation?

So are you saying that from your item’s DataTemplate you can’t get to the ListView? Because you can get from the ListView to the Node or to the Diagram, yes?

I have modified the sample to be more like my actual problem. The binding inside the using RelativeSource works in the first situation, and fails when the ‘Add’ button is used. I believe you are correct that the relative source does not have the visual tree setup inside the node. If you can suggest a way to get the third column in my to get the SharedLabel.

[code]
<Window x:Class="GoXamBrowser.MainWindow"
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:GoXamBrowser"
Title="MainWindow" Height="350" Width="525">



<Border Name="NodeBorder" BorderBrush="Gray" BorderThickness="2" CornerRadius="3" Background="Aqua"
go:Part.SelectionAdorned="True" go:Part.Resizable="True"
go:Node.FromSpot="AllSides" go:Node.ToSpot="AllSides"
go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}">
























<go:LinkShape x:Name="Path" StrokeThickness="2"
Stroke="{Binding Path=Part.IsSelected,
Converter={StaticResource theSelectedBrushConverter}}" />
<Polygon Fill="Black" Points="8 4 0 8 2 4 0 0" go:LinkPanel.Index="-1"
go:LinkPanel.Alignment="1 0.5" go:LinkPanel.Orientation="Along" />












<go:Diagram Grid.Row="1" x:Name="myDiagram"
Padding="10"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
NodeTemplate="{StaticResource FieldTemplate}"
LinkTemplate="{StaticResource ReferenceTemplate}" />


[/code]
Code-Behind:
[code]
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Northwoods.GoXam;
using Northwoods.GoXam.Model;
namespace GoXamBrowser
{
///
/// Interaction logic for MainWindow.xaml
///

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainModel("Sample");
var model = new GraphLinksModel();
model.Modifiable = true; // let the model be modified
model.NodeKeyPath = "Key"; // use the GraphModelNodeData.Key property
this.myDiagram.Model = model;
this.myDiagram.Layout = new Northwoods.GoXam.Layout.LayeredDigraphLayout();
myDiagram.StartTransaction("Init");
myDiagram.Model.AddNode(new SampleNode("First", "first node"));
myDiagram.CommitTransaction("Init");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
myDiagram.StartTransaction("Add");
myDiagram.Model.AddNode(new SampleNode(txtName.Text, "new node"));
myDiagram.CommitTransaction("Add");
}
}
public class MainModel
{
public MainModel(string label) { SharedLabel = label; }
public string SharedLabel { get; set; }
}
public class SampleNode : GraphLinksModelNodeData
{
public SampleNode(string name, string comment) : base()
{
Name = name;
Comment = comment;
Items = new ObservableCollection { new SampleItem(Name, "B1"), new SampleItem(Comment, "B2") };
}
public string Name { get; set; }
public string Comment { get; set; }
public ObservableCollection Items { get; set; }
}
public class SampleItem
{
public SampleItem(string a, string b) { A = a; B = b; }
public string A { get; set; }
public string B { get; set; }
}
public class SampleLink : GraphLinksModelLinkData
{
}
}
[/code]

Apparently data-binding RelativeSource FindAncestor uses the logical tree, not the visual tree.

So, the following changes (and unrelated simplifications) might get you what you want:

<Window x:Class="GoXamBrowser.MainWindow" 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:GoXamBrowser" Title="MainWindow" Height="370" Width="525"> <Window.Resources> <!-- the template for nodes --> <DataTemplate x:Key="FieldTemplate"> <Border Name="NodeBorder" BorderBrush="Gray" BorderThickness="2" CornerRadius="3" Background="Aqua" go:Part.SelectionAdorned="True" go:Part.Resizable="True" go:Node.FromSpot="AllSides" go:Node.ToSpot="AllSides" go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay}"> <StackPanel Orientation="Vertical"> <!--TextBlock Text="{Binding Path=Diagram.DataContext.SharedLabel, RelativeSource={RelativeSource TemplatedParent}}"/--> <TextBlock Text="{Binding Path=DataContext.SharedLabel, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"/> <TextBlock Text="{Binding Path=Data.Name}"/> <ListView ItemsSource="{Binding Path=Data.Items}"> <ListView.View> <GridView> <GridView.Columns> <GridViewColumn Width="60" DisplayMemberBinding="{Binding Path=A}"/> <GridViewColumn Width="60" DisplayMemberBinding="{Binding Path=B}"/> <GridViewColumn Width="60" DisplayMemberBinding="{Binding Path=DataContext.SharedLabel, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"/> </GridView.Columns> </GridView> </ListView.View> </ListView> </StackPanel> </Border> </DataTemplate> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <StackPanel Grid.Row="0" Orientation="Horizontal"> <Button Content="Add Node" Click="Button_Click"/> <TextBox Width="100" Name="txtName" Text="(new name)"/> </StackPanel> <local:LogicalDiagram Grid.Row="1" x:Name="myDiagram" Padding="10" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" NodeTemplate="{StaticResource FieldTemplate}" /> </Grid> </Window>

[code]using System;
using System.Collections.ObjectModel;
using System.Windows;
using Northwoods.GoXam;
using Northwoods.GoXam.Model;

namespace GoXamBrowser {
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
DataContext = new MainModel(“Sample”);
var model = new GraphLinksModel<SampleNode, String, String, SampleLink>();
model.Modifiable = true; // let the model be modified
myDiagram.Model = model;
myDiagram.Layout = new Northwoods.GoXam.Layout.LayeredDigraphLayout();
myDiagram.StartTransaction(“Init”);
myDiagram.Model.AddNode(new SampleNode(“First”, “first node”));
myDiagram.CommitTransaction(“Init”);
}
private void Button_Click(object sender, RoutedEventArgs e) {
myDiagram.StartTransaction(“Add”);
myDiagram.Model.AddNode(new SampleNode(txtName.Text, “new node”));
myDiagram.CommitTransaction(“Add”);
}
}
public class MainModel {
public MainModel(string label) { SharedLabel = label; }
public string SharedLabel { get; set; }
}
public class SampleNode : GraphLinksModelNodeData {
public SampleNode(string name, string comment) {
Name = name;
Comment = comment;
Items = new ObservableCollection { new SampleItem(Name, “B1”), new SampleItem(Comment, “B2”) };
}
public string Name { get; set; }
public string Comment { get; set; }
public ObservableCollection Items { get; set; }
}
public class SampleItem {
public SampleItem(string a, string b) { A = a; B = b; }
public string A { get; set; }
public string B { get; set; }
}
public class SampleLink : GraphLinksModelLinkData<String, String> {
}

// this only works in WPF
public class LogicalDiagram : Diagram {
public LogicalDiagram() {
this.PartManager = new LogicalPartManager();
}
public void AddLogical(Object x) { if (x != null) AddLogicalChild(x); }
public void RemoveLogical(Object x) { if (x != null) RemoveLogicalChild(x); }
}

public class LogicalPartManager : PartManager {
protected override void OnNodeAdded(Node node) {
base.OnNodeAdded(node);
var diag = this.Diagram as LogicalDiagram;
if (diag != null) diag.AddLogical(node);
}
protected override void OnNodeRemoved(Node node, NodeLayer layer) {
base.OnNodeRemoved(node, layer);
var diag = this.Diagram as LogicalDiagram;
if (diag != null) diag.RemoveLogical(node);
}
}
}[/code]
By the way, I tried this in version 1.2, not in 1.1.

Brilliant! That did the trick. Thanks.