バージョン

参照を持つ階層ノード データへのバインド (xamDiagram)

トピックの概要

目的

このトピックでは、xamDiagram™ コントロールを階層ノード データにバインドする方法を説明します。

前提条件

このトピックを理解するために、以下のトピックを参照することをお勧めします。

トピック 目的

このトピックでは、 xamDiagram コントロールがサポートするデータ バインディング シナリオの概要を説明します。

参照を持つ階層ノード データへの xamDiagram のバインド

概要

以下の手順では、入力データ オブジェクトがノードを表し、各ノードが子ノード オブジェクトのコレクションを持つデータに xamDiagram をバインドする方法を示します。

プレビュー

以下のスクリーンショットは結果のプレビューです。

xamDiagram Bind To Hierarchical Node Data With References 1.png

前提条件

この手順を実行するには、以下が必要です。

  • ページに追加される空の xamDiagram を持つ WPF アプリケーション

  • ForceDirectedGraphDiagramLayout のインスタンスに設定される xamDiagramLayout プロパティ

概要

以下はプロセスの概要です。

. ItemsSource プロパティの構成

. ノード定義の作成

. 接続定義の作成

手順

以下の手順では、参照を持つ階層ノード データに xamDiagram をバインドする方法を説明します。

1.ItemsSource の設定

. サンプルのデータ クラスを追加します。

以下の Employee クラスと Manager クラスをコード ビハインドに追加します。Manager クラスは、マネージャーの下位を含む Employee インスタンスがあるリスト プロパティを持ちます。このプロパティは、xamDiagramManager-Employee 関係を作成するために使用されます。親子タイプの継承関係に対する要件はなく、自己参照タイプを使用することもできます。

C# の場合:

public class Employee : INotifyPropertyChanged
{
    public Employee(string name)
    {
        Name = name;
    }
    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

public class Manager : Employee
{
    public Manager(string name) : base(name) { }

    private IList<Employee> _subordinates;
    public IList<Employee> Subordinates
    {
        get { return _subordinates; }
        set
        {
            _subordinates = value;
            OnPropertyChanged();
        }
    }
}

VB の場合:

Public Class Employee
    Implements INotifyPropertyChanged

    Public Sub New(name As String)
        Name = name
    End Sub

    Private _name As String
    Public Property Name() As String
        Get
            Return _name
        End Get
        Set(value As String)
            _name = 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 Manager
    Inherits Employee

    Public Sub New(name As String)
        MyBase.New(name)
    End Sub

    Private _subordinates As IList(Of Employee)
    Public Property Subordinates() As IList(Of Employee)
        Get
            Return _subordinates
        End Get
        Set(value As IList(Of Employee))
            _subordinates = value
            OnPropertyChanged()
        End Set
    End Property
End Class

ビュー モデル クラスを追加します。

xamDiagram がバインドされる以下のビュー モデル クラスを追加します。

C# の場合:

public class EmployeeViewModel : INotifyPropertyChanged
{
    public EmployeeViewModel()
    {
        var employees = new ObservableCollection<Employee>();
        var sharedEmployee = new Employee("Shared Employee");
        employees.Add(new Manager("Manager 1")
        {
            Subordinates = new List<Employee>()
            {
                new Employee("Employee 1"),
                new Employee("Employee 2"),
                new Employee("Employee 3"),
                new Employee("Employee 4"),
                sharedEmployee
            }
        });
        employees.Add(new Manager("Manager 2")
        {
            Subordinates = new List<Employee>()
            {
                sharedEmployee,
                new Employee("Employee 5"),
                new Employee("Employee 6"),
                new Employee("Employee 7"),
                new Employee("Employee 8"),
                new Employee("Employee 9")
            }
        });
        employees.Add(new Employee("Employee 10"));
        Employees = employees;
    }

    private IList<Employee> _employees;
    public IList<Employee> Employees
    {
        get { return _employees; }
        set
        {
            _employees = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

VB の場合:

Public Class EmployeeViewModel
    Implements INotifyPropertyChanged

    Public Sub New()
        Dim employees = New ObservableCollection(Of Employee)()
        Dim sharedEmployee = New Employee("Shared Employee")

        employees.Add(New Manager("Manager 1") With { _
            .Subordinates = New List(Of Employee)() From { _
                New Employee("Employee 1"), _
                New Employee("Employee 2"), _
                New Employee("Employee 3"), _
                New Employee("Employee 4"), _
                sharedEmployee _
            } _
        })
        employees.Add(New Manager("Manager 2") With { _
            .Subordinates = New List(Of Employee)() From { _
                sharedEmployee, _
                New Employee("Employee 5"), _
                New Employee("Employee 6"), _
                New Employee("Employee 7"), _
                New Employee("Employee 8"), _
                New Employee("Employee 9") _
            } _
        })
        employees.Add(New Employee("Employee 10"))
        Employees = employees
    End Sub

    Private _employees As IList(Of Employee)
    Public Property Employees() As IList(Of Employee)
        Get
            Return _employees
        End Get
        Set(value As IList(Of Employee))
            _employees = 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

ItemsSource` プロパティを設定します。

DataContext をビュー モデル クラスの新しいインスタンスに設定し、 ItemsSourceEmployeeViewModel クラスの Employees プロパティにバインドします。

XAML の場合:

<ig:XamDiagram x:Name="HierarchicalDiagram"
    ItemsSource="{Binding Employees}">
    <ig:XamDiagram.DataContext>
        <local:EmployeeViewModel/>
    </ig:XamDiagram.DataContext>
</ig:XamDiagram>

2.ノード定義の作成

通常、 ItemsSource および NodeDefinition の各データ タイプが xamDiagram に追加されます。1 つ以上のタイプに継承関係がある場合、最初に、最も具体的なタイプを指定する必要があります。xamDiagram は、各データ項目のタイプをノード定義の TargetType に一致させようとします。その TargetTypeIsAssignableFrom への呼び出しに対し true を返す、最初のノード定義が選択されます。つまり、ノード定義の TargetType が完全に一致する場合、またはデータ項目のタイプが親タイプである場合、ノード定義が選択されます。

Manager クラスの NodeDefinition を追加します。

  1. NodeDefinitionTargetTypeManager タイプに設定します。

  2. ChildrenMemberPath を子オブジェクトのコレクションを保持するプロパティの名前に設定します。
    この場合は「Subordinates」プロパティです。

  3. DisplayMemberPath を設定します。 DisplayMemberPath を指定しないで、NodeStyle でカスタム DisplayTemplate を設定しない場合、ToString メソッドの結果はノードのコンテンツとして表示されます。

  4. (オプション) NodeStyle を設定します。
    NodeStyle プロパティを使用すると、ノード定義によって一致するすべての DiagramNode オブジェクトに適用するスタイルを設定できます。これにより、特定のデータ タイプに対して作成されたノードのカスタマイズが容易になります。

XAML の場合:

<ig:NodeDefinition
    TargetType="{x:Type local:Manager}"
    ChildrenMemberPath="Subordinates"
    DisplayMemberPath="Name">
    <ig:NodeDefinition.NodeStyle>
        <Style TargetType="ig:DiagramNode">
            <Setter Property="FontSize" Value="18"/>
            <Setter Property="Fill" Value="Green"/>
            <Setter Property="ShapeType" Value="Ellipse"/>
            <Setter Property="Stroke" Value="Transparent"/>
        </Style>
    </ig:NodeDefinition.NodeStyle>
</ig:NodeDefinition>

.Employee クラスのノード定義を追加します。

TargetTypeDisplayMemberPath を定義するノード定義を追加します。DisplayTemplate プロパティのセッターを使用して、 NodeStyle を以下のように設定します。

XAML の場合:

<ig:NodeDefinition
    TargetType="{x:Type local:Employee}">
    <ig:NodeDefinition.NodeStyle>
        <Style TargetType="ig:DiagramNode">
            <Setter Property="DisplayTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <TextBlock
                            HorizontalAlignment="Center"
                            Text="{Binding Name}"
                            Foreground="Green"/>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="Fill" Value="LightGreen"/>
            <Setter Property="Stroke" Value="Transparent"/>
        </Style>
    </ig:NodeDefinition.NodeStyle>
</ig:NodeDefinition>

3.階層接続定義の作成

ConnectionDefinition を作成し、 ConnectionDefinitions コレクションに追加します。接続定義では、 xamDiagram が生成するデータ項目の親子関係の接続のカスタム スタイルを設定できます。接続定義は、 StartTargetType プロパティと EndTargetType プロパティで一致が行われます。この例では、Manager タイプと Employee タイプに接続定義を設定します。

ConnectionStyle プロパティを、 DiagramConnection をターゲットとするスタイルに設定します。

XAML の場合:

<ig:ConnectionDefinition
    StartTargetType="{x:Type local:Manager}"
    EndTargetType="{x:Type local:Employee}">
    <ig:ConnectionDefinition.ConnectionStyle>
        <Style TargetType="ig:DiagramConnection">
            <Setter Property="Stroke" Value="DarkGreen"/>
            <Setter Property="Foreground" Value="DarkGreen"/>
            <Setter Property="Fill" Value="DarkGreen"/>
            <Setter Property="Content" Value="Reports to"/>
            <Setter Property="EndCapType" Value="None"/>
            <Setter Property="StartCapType" Value="FilledArrow"/>
        </Style>
    </ig:ConnectionDefinition.ConnectionStyle>
</ig:ConnectionDefinition>

全コード

以下は、この手順の完全なコードです。

XAML の場合:

<UserControl x:Class="DiagramDocumentationSamples.HierararchicalReferencesData"
    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="HierarchicalDiagram" ItemsSource="{Binding Employees}">
        <ig:XamDiagram.DataContext>
            <local:EmployeeViewModel/>
        </ig:XamDiagram.DataContext>

        <ig:XamDiagram.NodeDefinitions>
            <ig:NodeDefinition
                TargetType="{x:Type local:Manager}"
                ChildrenMemberPath="Subordinates"
                DisplayMemberPath="Name">
                <ig:NodeDefinition.NodeStyle>
                    <Style TargetType="ig:DiagramNode">
                        <Setter Property="FontSize" Value="18"/>
                        <Setter Property="Fill" Value="Green"/>
                        <Setter Property="ShapeType" Value="Ellipse"/>
                        <Setter Property="Stroke" Value="Transparent"/>
                    </Style>
                </ig:NodeDefinition.NodeStyle>
            </ig:NodeDefinition>
            <ig:NodeDefinition
                TargetType="{x:Type local:Employee}">
                <ig:NodeDefinition.NodeStyle>
                    <Style TargetType="ig:DiagramNode">
                        <Setter Property="DisplayTemplate">
                            <Setter.Value>
                                <DataTemplate>
                                    <TextBlock
                                        HorizontalAlignment="Center"
                                        Text="{Binding Name}"
                                        Foreground="Green"/>
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Fill" Value="LightGreen"/>
                        <Setter Property="Stroke" Value="Transparent"/>
                    </Style>
                </ig:NodeDefinition.NodeStyle>
            </ig:NodeDefinition>
        </ig:XamDiagram.NodeDefinitions>

        <ig:XamDiagram.ConnectionDefinitions>
            <ig:ConnectionDefinition
                StartTargetType="{x:Type local:Manager}"
                EndTargetType="{x:Type local:Employee}">
                <ig:ConnectionDefinition.ConnectionStyle>
                    <Style TargetType="ig:DiagramConnection">
                        <Setter Property="Stroke" Value="DarkGreen"/>
                        <Setter Property="Foreground" Value="DarkGreen"/>
                        <Setter Property="Fill" Value="DarkGreen"/>
                        <Setter Property="Content" Value="Reports to"/>
                        <Setter Property="EndCapType" Value="None"/>
                        <Setter Property="StartCapType" Value="FilledArrow"/>
                    </Style>
                </ig:ConnectionDefinition.ConnectionStyle>
            </ig:ConnectionDefinition>
        </ig:XamDiagram.ConnectionDefinitions>

        <ig:XamDiagram.Layout>
            <ig:ForceDirectedGraphDiagramLayout/>
        </ig:XamDiagram.Layout>
    </ig:XamDiagram>
</UserControl>

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 HierararchicalReferencesData : UserControl
    {
        public HierararchicalReferencesData()
        {
            InitializeComponent();
        }
    }

    public class Employee : INotifyPropertyChanged
    {
        public Employee(string name)
        {
            Name = name;
        }

        private string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class Manager : Employee
    {
        public Manager(string name) : base(name) { }

        private IList<Employee> _subordinates;
        public IList<Employee> Subordinates
        {
            get { return _subordinates; }
            set
            {
                _subordinates = value;
                OnPropertyChanged();
            }
        }
    }

    public class EmployeeViewModel : INotifyPropertyChanged
    {
        public EmployeeViewModel()
        {
            var employees = new ObservableCollection<Employee>();
            var sharedEmployee = new Employee("Shared Employee");
            employees.Add(new Manager("Manager 1")
            {
                Subordinates = new List<Employee>()
                {
                    new Employee("Employee 1"),
                    new Employee("Employee 2"),
                    new Employee("Employee 3"),
                    new Employee("Employee 4"),
                    sharedEmployee
                }
            });
            employees.Add(new Manager("Manager 2")
            {
                Subordinates = new List<Employee>()
                {
                    sharedEmployee,
                    new Employee("Employee 5"),
                    new Employee("Employee 6"),
                    new Employee("Employee 7"),
                    new Employee("Employee 8"),
                    new Employee("Employee 9")
                }
            });
            employees.Add(new Employee("Employee 10"));
            Employees = employees;
        }

        private IList<Employee> _employees;
        public IList<Employee> Employees
        {
            get { return _employees; }
            set
            {
                _employees = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

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 HierararchicalReferencesData
        Inherits UserControl

        Public Sub New()
            InitializeComponent()
        End Sub
    End Class

    Public Class Employee
        Implements INotifyPropertyChanged

        Public Sub New(name As String)
            Name = name
        End Sub

        Private _name As String
        Public Property Name() As String
            Get
                Return _name
            End Get
            Set(value As String)
                _name = 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 Manager
        Inherits Employee

        Public Sub New(name As String)
            MyBase.New(name)
        End Sub

        Private _subordinates As IList(Of Employee)
        Public Property Subordinates() As IList(Of Employee)
            Get
                Return _subordinates
            End Get
            Set(value As IList(Of Employee))
                _subordinates = value
                OnPropertyChanged()
            End Set
        End Property
    End Class

    Public Class EmployeeViewModel
        Implements INotifyPropertyChanged

        Public Sub New()
            Dim employees = New ObservableCollection(Of Employee)()
            Dim sharedEmployee = New Employee("Shared Employee")

            employees.Add(New Manager("Manager 1") With { _
                .Subordinates = New List(Of Employee)() From { _
                    New Employee("Employee 1"), _
                    New Employee("Employee 2"), _
                    New Employee("Employee 3"), _
                    New Employee("Employee 4"), _
                    sharedEmployee _
                } _
            })
            employees.Add(New Manager("Manager 2") With { _
                .Subordinates = New List(Of Employee)() From { _
                    sharedEmployee, _
                    New Employee("Employee 5"), _
                    New Employee("Employee 6"), _
                    New Employee("Employee 7"), _
                    New Employee("Employee 8"), _
                    New Employee("Employee 9") _
                } _
            })
            employees.Add(New Employee("Employee 10"))
            Employees = employees
        End Sub

        Private _employees As IList(Of Employee)
        Public Property Employees() As IList(Of Employee)
            Get
                Return _employees
            End Get
            Set(value As IList(Of Employee))
                _employees = 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

関連コンテンツ

このトピックの追加情報については、以下のトピックも合わせてご参照ください。

トピック 目的

このトピックでは、入力データ オブジェクトがノードおよび接続を表し、各接続オブジェクトが開始ノードと終了ノードを表す 2 つのノード オブジェクトへの参照を持つデータに、 xamDiagram コントロールをバインドする方法の手順を説明します。

このトピックでは、入力データ オブジェクトがノードおよび接続を表すデータに xamDiagram コントロールをバインドする方法の手順を説明します。ノード オブジェクトはそれぞれ一意の文字列識別子を持ち、接続オブジェクトはそれぞれ開始ノードと終了ノードを表す 2 つのノード オブジェクトの識別子を保持する 2 つのプロパティを持ちます。

このトピックでは、キーを持つ階層ノード データに xamDiagram コントロールをバインドする方法を説明します。