This topic provides a step by step guidance on how to bind the xamDiagram™ control to data where input data objects represent nodes and connections and each of the connection objects has a reference to two node objects representing its start and end nodes.
The following topics are prerequisites to understanding this topic:
The following procedure demonstrates how to bind the xamDiagram to data objects that represent nodes and connections, and each of the connection objects has a reference to two node objects representing its start and end nodes.
The following screenshot is a preview of the result.
To complete the procedure, you need the following:
A WPF application with an empty xamDiagram added to a page
The Layout property of the xamDiagram set to an instance of the ForceDirectedGraphDiagramLayout
Following is a conceptual overview of the process:
Setting the ItemsSource and ConnectionSource
Creating the node definitions
Creating the connection definitions
The following steps demonstrate how to bind the xamDiagram to hierarchical node data with references.
Add the sample node data class
Add the following WikipediaArticle
class to the code behind. The WikipediaArticle
represents the node object and has a single string property called Title
.
In C#:
public class WikipediaArticle : INotifyPropertyChanged
{
public WikipediaArticle(string title)
{
Title = title;
}
private string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
In VB.NET:
Public Class WikipediaArticle Implements INotifyPropertyChanged
Public Sub New(title As String)
Title = title
End Sub
Private _title As String
Public Property Title() As String
Get
Return _title
End Get
Set(value As String)
_title = value
OnPropertyChanged()
End Set
End Property
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Sub OnPropertyChanged(Optional propertyName As String = "")
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
Add the sample connection class
Add the following WikipediaLink
class to the code behind. The WikipediaLink
class represents a directed connection between two WikipediaArticle
instances.
In C#:
public class WikipediaLink : INotifyPropertyChanged
{
public WikipediaLink(WikipediaArticle fromArticle, WikipediaArticle toArticle)
{
FromArticle = fromArticle;
ToArticle = toArticle;
}
private WikipediaArticle _from;
public WikipediaArticle FromArticle
{
get { return _from; }
set
{
_from = value;
OnPropertyChanged();
}
}
private WikipediaArticle _to;
public WikipediaArticle ToArticle
{
get { return _to; }
set
{
_to = value;
OnPropertyChanged();
}
}
public override string ToString()
{
return string.Empty;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
In VB.NET:
Public Class WikipediaLink
Implements INotifyPropertyChanged
Public Sub New(fromArticle As WikipediaArticle, toArticle As WikipediaArticle)
FromArticle = fromArticle
ToArticle = toArticle
End Sub
Private _from As WikipediaArticle
Public Property FromArticle() As WikipediaArticle
Get
Return _from
End Get
Set
_from = value
OnPropertyChanged()
End Set
End Property
Private _to As WikipediaArticle
Public Property ToArticle() As WikipediaArticle
Get
Return _to
End Get
Set
_to = value
OnPropertyChanged()
End Set
End Property
Public Overrides Function ToString() As String
Return String.Empty
End Function
Public Event PropertyChanged As PropertyChangedEventHandler
Protected Sub OnPropertyChanged( Optional propertyName As String = "")
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
Add the data items
Add the following LinkChainViewModel
class which exposes two list properties – for nodes and for connections and is automatically populated with some sample data.
In C#:
public class LinkChainViewModel : INotifyPropertyChanged
{
public LinkChainViewModel()
{
var travolta = new WikipediaArticle("John Travolta");
var hubbard = new WikipediaArticle("L. Ron Hubbard");
var astoria = new WikipediaArticle("Astoria, Oregon");
var goonies = new WikipediaArticle("The Goonies");
var feldman = new WikipediaArticle("Corey Feldman");
var jackson = new WikipediaArticle("Michael Jackson");
var year2001 = new WikipediaArticle("2001");
var year2001music = new WikipediaArticle("2001 in music");
Articles = new ObservableCollection<WikipediaArticle>()
{
travolta,
hubbard,
astoria,
goonies,
feldman,
jackson,
year2001,
year2001music
};
Links = new ObservableCollection<WikipediaLink>()
{
new WikipediaLink(travolta, hubbard),
new WikipediaLink(hubbard, astoria),
new WikipediaLink(astoria, goonies),
new WikipediaLink(goonies, feldman),
new WikipediaLink(feldman, jackson),
new WikipediaLink(travolta, year2001),
new WikipediaLink(year2001, year2001music),
new WikipediaLink(year2001music, jackson)
};
}
private IList<WikipediaArticle> _articles;
public IList<WikipediaArticle> Articles
{
get { return _articles; }
set
{
_articles = value;
OnPropertyChanged();
}
}
private IList<WikipediaLink> _links;
public IList<WikipediaLink> Links
{
get { return _links; }
set
{
_links = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
In VB.NET:
Public Class LinkChainViewModel
Implements INotifyPropertyChanged
Public Sub New()
Dim travolta = New WikipediaArticle("John Travolta")
Dim hubbard = New WikipediaArticle("L. Ron Hubbard")
Dim astoria = New WikipediaArticle("Astoria, Oregon")
Dim goonies = New WikipediaArticle("The Goonies")
Dim feldman = New WikipediaArticle("Corey Feldman")
Dim jackson = New WikipediaArticle("Michael Jackson")
Dim year2001 = New WikipediaArticle("2001")
Dim year2001music = New WikipediaArticle("2001 in music")
Articles = New ObservableCollection(Of WikipediaArticle)() From { _
travolta, _
hubbard, _
astoria, _
goonies, _
feldman, _
jackson, _
year2001, _
year2001music _
}
Links = New ObservableCollection(Of WikipediaLink)() From { _
New WikipediaLink(travolta, hubbard), _
New WikipediaLink(hubbard, astoria), _
New WikipediaLink(astoria, goonies), _
New WikipediaLink(goonies, feldman), _
New WikipediaLink(feldman, jackson), _
New WikipediaLink(travolta, year2001), _
New WikipediaLink(year2001, year2001music), _
New WikipediaLink(year2001music, jackson) _
}
End Sub
Private _articles As IList(Of WikipediaArticle)
Public Property Articles() As IList(Of WikipediaArticle)
Get
Return _articles
End Get
Set(value As IList(Of WikipediaArticle))
_articles = value
OnPropertyChanged()
End Set
End Property
Private _links As IList(Of WikipediaLink)
Public Property Links() As IList(Of WikipediaLink)
Get
Return _links
End Get
Set(value As IList(Of WikipediaLink))
_links = value
OnPropertyChanged()
End Set
End Property
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Sub OnPropertyChanged(Optional propertyName As String = "")
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
Set the DataContext of the XamDiagram
Set the diagram’s DataContext
property to an instance of the LinkChainViewModel
class.
In XAML:
<ig:XamDiagram>
<ig:XamDiagram.DataContext>
<local:LinkChainViewModel/>
</ig:XamDiagram.DataContext>
</ig:XamDiagram>
Set the ItemsSource property
Bind the ItemsSource to the Articles
property of the LinkChainViewModel
data context.
In XAML:
ItemsSource="{Binding Articles}"
Set the ConnectionsSource property
Bind the ConnectionsSource to the Links
property of the LinkChainViewModel
data context.
In XAML:
ConnectionsSource="{Binding Links}"
For each of the data types in the ItemsSource a NodeDefinition is usually added to the xamDiagram . Specify the most concrete types first if one or more types are in an inheritance relationship. The xamDiagram tries to match the type of each of the data items in the TargetType of a node definition. The first node definition whose TargetType returns true from a call to IsAssignableFrom
is selected. That is if the TargetType of the node definition matches exactly, or is a parent type of the data item’s type; otherwise, the node definition is selected.
Create a NodeDefinition for the Manager class
Set the TargetType of the NodeDefinition to the WikipediaArticle
type.
Set the DisplayMemberPath to Title. Not specifying a DisplayMemberPath, and not setting a custom DisplayTemplate via the NodeStyle, results in the ToString
method displayed as the nodes’ content.
Set the NodeStyle (optional)
Using the NodeStyle property, you can set the style to be applied to all DiagramNode
objects matched by the node definition. This gives you the opportunity to easily customize the nodes created for a certain data type.
In XAML:
<ig:XamDiagram.NodeDefinitions>
<ig:NodeDefinition
TargetType="local:WikipediaArticle"
DisplayMemberPath="Title"/>
</ig:XamDiagram.NodeDefinitions>
When supplying separate connection data objects, use an instance of ConnectionSourceDefinition in the diagram’s ConnectionDefinitions. This type of connection definition describes what connection to create for each data items matching the definition’s TargetType. In order for such a connection to have its StartNode and EndNode properties correctly populated, the connection definition’s StartNodeMemberPath and EndNodeMemberPath properties must be set to the names of the properties holding the start/end node data object references.
Create a ConnectionSourceDefinition and add it to the ConnectionDefinitions collection.
Set the TargetType to the WikipediaLink
type.
Set the StartNodeMemberPath to "FromArticle" . Set the EndNodeMemberPath to "ToArticle" .
Set the ConnectionStyle (optional)
You can customize the connections created for a particular data type by setting the ConnectionStyle property to a style targeting DiagramConnection. You can specify a setting for the DisplayTemplate property and apply a template where the data object will be set as the DataContext
.
In XAML:
<ig:XamDiagram.ConnectionDefinitions>
<ig:ConnectionSourceDefinition
TargetType="local:WikipediaLink"
StartNodeMemberPath="FromArticle"
EndNodeMemberPath="ToArticle"/>
</ig:XamDiagram.ConnectionDefinitions>
Following is the full code for this procedure.
In XAML:
<UserControl x:Class="DiagramDocumentationSamples.NodesConnectionsReferencesData"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ig="http://schemas.infragistics.com/xaml"
xmlns:local="clr-namespace:DiagramDocumentationSamples"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<ig:XamDiagram
x:Name="FlatDataDiagram"
ItemsSource="{Binding Articles}"
ConnectionsSource="{Binding Links}">
<ig:XamDiagram.DataContext>
<local:LinkChainViewModel/>
</ig:XamDiagram.DataContext>
<ig:XamDiagram.NodeDefinitions>
<ig:NodeDefinition
TargetType="local:WikipediaArticle"
DisplayMemberPath="Title"/>
</ig:XamDiagram.NodeDefinitions>
<ig:XamDiagram.ConnectionDefinitions>
<ig:ConnectionSourceDefinition
TargetType="local:WikipediaLink"
StartNodeMemberPath="FromArticle"
EndNodeMemberPath="ToArticle"/>
</ig:XamDiagram.ConnectionDefinitions>
<ig:XamDiagram.Layout>
<ig:ForceDirectedGraphDiagramLayout/>
</ig:XamDiagram.Layout>
</ig:XamDiagram>
</UserControl>
In C#:
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Controls;
namespace DiagramDocumentationSamples
{
public partial class NodesConnectionsReferencesData : UserControl
{
public NodesConnectionsReferencesData()
{
InitializeComponent();
}
}
public class WikipediaArticle : INotifyPropertyChanged
{
public WikipediaArticle(string title)
{
Title = title;
}
private string _title;
public string Title
{
get { return _title; }
set
{
_title = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public class WikipediaLink : INotifyPropertyChanged
{
public WikipediaLink(WikipediaArticle fromArticle, WikipediaArticle toArticle)
{
FromArticle = fromArticle;
ToArticle = toArticle;
}
private WikipediaArticle _from;
public WikipediaArticle FromArticle
{
get { return _from; }
set
{
_from = value;
OnPropertyChanged();
}
}
private WikipediaArticle _to;
public WikipediaArticle ToArticle
{
get { return _to; }
set
{
_to = value;
OnPropertyChanged();
}
}
public override string ToString()
{
return string.Empty;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public class LinkChainViewModel : INotifyPropertyChanged
{
public LinkChainViewModel()
{
var travolta = new WikipediaArticle("John Travolta");
var hubbard = new WikipediaArticle("L. Ron Hubbard");
var astoria = new WikipediaArticle("Astoria, Oregon");
var goonies = new WikipediaArticle("The Goonies");
var feldman = new WikipediaArticle("Corey Feldman");
var jackson = new WikipediaArticle("Michael Jackson");
var year2001 = new WikipediaArticle("2001");
var year2001music = new WikipediaArticle("2001 in music");
Articles = new ObservableCollection<WikipediaArticle>()
{
travolta,
hubbard,
astoria,
goonies,
feldman,
jackson,
year2001,
year2001music
};
Links = new ObservableCollection<WikipediaLink>()
{
new WikipediaLink(travolta, hubbard),
new WikipediaLink(hubbard, astoria),
new WikipediaLink(astoria, goonies),
new WikipediaLink(goonies, feldman),
new WikipediaLink(feldman, jackson),
new WikipediaLink(travolta, year2001),
new WikipediaLink(year2001, year2001music),
new WikipediaLink(year2001music, jackson)
};
}
private IList<WikipediaArticle> _articles;
public IList<WikipediaArticle> Articles
{
get { return _articles; }
set
{
_articles = value;
OnPropertyChanged();
}
}
private IList<WikipediaLink> _links;
public IList<WikipediaLink> Links
{
get { return _links; }
set
{
_links = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
In VB:
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.ComponentModel
Imports System.Runtime.CompilerServices
Imports System.Windows.Controls
Namespace DiagramDocumentationSamples
Public Partial Class NodesConnectionsReferencesData
Inherits UserControl
Public Sub New()
InitializeComponent()
End Sub
End Class
Public Class WikipediaArticle
Implements INotifyPropertyChanged
Public Sub New(title As String)
Title = title
End Sub
Private _title As String
Public Property Title() As String
Get
Return _title
End Get
Set(value As String)
_title = value
OnPropertyChanged()
End Set
End Property
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Sub OnPropertyChanged(Optional propertyName As String = "")
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
Public Class WikipediaLink
Implements INotifyPropertyChanged
Public Sub New(fromArticle As WikipediaArticle, toArticle As WikipediaArticle)
FromArticle = fromArticle
ToArticle = toArticle
End Sub
Private _from As WikipediaArticle
Public Property FromArticle() As WikipediaArticle
Get
Return _from
End Get
Set(value As WikipediaArticle)
_from = value
OnPropertyChanged()
End Set
End Property
Private _to As WikipediaArticle
Public Property ToArticle() As WikipediaArticle
Get
Return _to
End Get
Set(value As WikipediaArticle)
_to = value
OnPropertyChanged()
End Set
End Property
Public Overrides Function ToString() As String
Return String.Empty
End Function
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Sub OnPropertyChanged(Optional propertyName As String = "")
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
Public Class LinkChainViewModel
Implements INotifyPropertyChanged
Public Sub New()
Dim travolta = New WikipediaArticle("John Travolta")
Dim hubbard = New WikipediaArticle("L. Ron Hubbard")
Dim astoria = New WikipediaArticle("Astoria, Oregon")
Dim goonies = New WikipediaArticle("The Goonies")
Dim feldman = New WikipediaArticle("Corey Feldman")
Dim jackson = New WikipediaArticle("Michael Jackson")
Dim year2001 = New WikipediaArticle("2001")
Dim year2001music = New WikipediaArticle("2001 in music")
Articles = New ObservableCollection(Of WikipediaArticle)() From { _
travolta, _
hubbard, _
astoria, _
goonies, _
feldman, _
jackson, _
year2001, _
year2001music _
}
Links = New ObservableCollection(Of WikipediaLink)() From { _
New WikipediaLink(travolta, hubbard), _
New WikipediaLink(hubbard, astoria), _
New WikipediaLink(astoria, goonies), _
New WikipediaLink(goonies, feldman), _
New WikipediaLink(feldman, jackson), _
New WikipediaLink(travolta, year2001), _
New WikipediaLink(year2001, year2001music), _
New WikipediaLink(year2001music, jackson) _
}
End Sub
Private _articles As IList(Of WikipediaArticle)
Public Property Articles() As IList(Of WikipediaArticle)
Get
Return _articles
End Get
Set(value As IList(Of WikipediaArticle))
_articles = value
OnPropertyChanged()
End Set
End Property
Private _links As IList(Of WikipediaLink)
Public Property Links() As IList(Of WikipediaLink)
Get
Return _links
End Get
Set(value As IList(Of WikipediaLink))
_links = value
OnPropertyChanged()
End Set
End Property
Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
Protected Sub OnPropertyChanged(Optional propertyName As String = "")
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
End Namespace
The following topics provide additional information related to this topic.