Binding to LinksInto problem

Hi all,

I am basically using the LinksInto and LinksOutOf properties to set the visibility of “Show/Hide Children” and “Show/Hide Parents” buttons on my Nodes.
I use a converter to convert the LinksInto property to a Visiblility, Collapsed or Visible and Bind to Node.LinksInto using the converter in xaml.

This works fine the first time I load the diagram, and hides/shows the buttons correctly, however if I then refresh the diagram by setting the nodesource again (the underlying data can change), the LinksInto and LinksOutof counts always return 0.

What am I doing wrong ?

Incedently, what is the best way to get the chart to redraw, sometimes we have different charts on multiple tabs, and when we switch tabs, the control only seems to draw the first node, although all links are drawn, when we scroll the view the nodes reappear.

Many thanks

Dave

Those Node properties, such as Node.LinksInto, are not dependency properties, so binding to them won’t necessarily be able to handle changes to those collections.

Setting the Visibility of Buttons is done in two different ways in the samples.

In IncrementalTree it’s set in the CollapseExpandButton_Click event handler.

In VisualTree it’s bound to the data via a custom converter that returns Visible or Collapsed depending on how many visual tree children that data (a UIElement) has.

I don’t know what might be causing Node.LinksInto to return zero after resetting the model’s nodes source. That causes all of the Nodes and Links to be discarded and replacements to be constructed based on the new data. If you are using a GraphLinksModel, are you also resetting the model’s LinksSource property, so that it matches up with the new NodesSource collection?

What platform and version are you using?

Goxam 1.08
Silverlight 3
Xp

I todged the Orgchart static example as a test case, with the same results.

I added a simple Load method …

public void Load()
{
var model = new TreeModel<TreeModelNodeData, String>();
model.NodeKeyPath = “Key”;
model.ParentNodePath = “ParentKey”;
orgs = new ObservableCollection<TreeModelNodeData>();
model.NodesSource = orgs;
orgs.Add(new TreeModelNodeData()
{
Key = “Alpha”,
ParentKey = “”
});
orgs.Add(new TreeModelNodeData()
{
Key = “Beta”,
ParentKey = “Alpha”
});
orgs.Add(new TreeModelNodeData()
{
Key = “Gamma”,
ParentKey = “Alpha”
});
orgs.Add(new TreeModelNodeData()
{
Key = “Delta”,
ParentKey = “Gamma”
});

    myDiagram.Model = model;
}

And the converter for the Show/Hide Children Button visibility property…

public class ConverterVisibility : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Node n = value as Node;
if (n.LinksOutOf.Count() > 0)
return Visibility.Visible;
else
return Visibility.Collapsed;

  }

  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  {
      throw new NotImplementedException();
  }

}

First time round this works fine, when Loading again, the LinksOutOf count is always 0.

Many thanks
Dave

The problem with that converter is basically the same as what I said before about it not notifying about changes (being a DependencyProperty or an ObservableCollection).

The reason is that when you re-set the model data it rebuilds the diagram’s Nodes. So when the first node data (a tree root) is seen in the NodesSource collection, it builds a corresponding Node, including applying the DataTemplate that uses your converter.

But at this time, there’s just one Node and no Links, so of course the value of Node.LinksOutOf is an empty collection.

Then the other node data are seen, and corresponding Nodes and Links are created. Now the root Node does have two Links in its LinksOutOf collection. But because it’s not an ObservableCollection (and because there’s no data-binding on that property anyway), nothing changes within the elements of that Node.

I’ll bet if you reversed the order of the node data in your collection you wouldn’t have noticed any problem.

On the other hand, if you changed the converter to look at the model to see what relationships really do exist, everything works as you would expect:

if (n.Diagram.Model.GetToNodesForNode(n.Data).Count() > 0) ...

And now the order of node data shouldn’t matter, because this predicate doesn’t depend on the order in which Nodes are built from the DataTemplates.

An alternative would be to use the TreeModelNodeData.ChildKeys property, instead of the ParentKey property. Then you could do:

var d = n.Data as TreeModelNodeData<String>;
if (d.ChildKeys.Count() > 0) ...