C#のWPFでTreeViewへデータをバインドする

タイトル

ツリー構造を展開したり折りたたんだりして表示できるTreeViewコントロール。
このTreeViewへデータをバインドするには、ItemTemplateへHierarchicalDataTemplateを定義して使う。


バインドさせるデータを格納するクラス


    public class TreeSource : INotifyPropertyChanged
    {
        private bool                             _IsExpanded = true;
        private string                           _Text       = "";
        private TreeSource                       _Parent     = null;
        private ObservableCollection<TreeSource> _Children   = null;


        public bool IsExpanded
        {
            get { return _IsExpanded; }
            set { _IsExpanded = value; OnPropertyChanged("IsExpanded"); }
        }

        public string Text
        {
            get { return _Text; }
            set { _Text = value; OnPropertyChanged("Text"); }
        }

        public TreeSource Parent
        {
            get { return _Parent; }
            set { _Parent = value; OnPropertyChanged("Parent"); }
        }

        public ObservableCollection<TreeSource> Children
        {
            get { return _Children; }
            set { _Children = value; OnPropertyChanged("Children"); }
        }



        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string name)
        {
            if (null == this.PropertyChanged) return;
            this.PropertyChanged(this, new PropertyChangedEventArgs(name));
        }

        public void Add(TreeSource child)
        {
            if (null == Children) Children = new ObservableCollection<TreeSource>();
            child.Parent = this;
            Children.Add(child);
        }
    }

プロパティ変更が正しく通知されるようINotifyPropertyChangedインターフェースを実装。

IsExpandedプロパティ

展開されているか折りたたまれているかを格納。

Textプロパティ

表示する文字列。

Childrenプロパティ

子要素となるデータを格納する。

Parentプロパティ

親要素を格納する事で階層をさかのぼって参照出来るようにしている。
Parentプロパティを正しくセットする為、Addメソッドを作っている。(42~47行目)
 

XAML


<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="200" Width="250">
    <Grid Margin="20">
        <TreeView ItemsSource="{Binding TreeRoot}">
            <TreeView.Resources>
                <Style TargetType="TreeViewItem">
                    <Setter Property="IsExpanded" Value="{Binding Path=IsExpanded,Mode=TwoWay}"/>
                </Style>
            </TreeView.Resources>
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate DataType="{x:Type local:TreeSource}" ItemsSource="{Binding Children}">
                    <TextBlock Text="{Binding Text}"/>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</Window>

IsExpandedをバインド (12~14行目)

TreeViewItemのStyle定義を追加して、TreeViewItemのIsExpandedプロパティへTreeSourceのIsExpandedプロパティをバインドする。

HierarchicalDataTemplateを定義 (16から20行目)

TreeView.ItemTemplateをつかって、HierarchicalDataTemplateを定義する。
HierarchicalDataTemplateのDataTypeにデータの型をセット。
HierarchicalDataTemplateのItemsSourceには子要素となるChildrenプロパティをバインドする。
HierarchicalDataTemplate内にTextBlockを配置してTextプロパティを表示させる。
 

本体のソース


    public partial class MainWindow : Window
    {
        public ObservableCollection<TreeSource> TreeRoot { get; set; }


        public MainWindow()
        {
            InitializeComponent();

            TreeRoot = new ObservableCollection<TreeSource>();
            var item1  = new TreeSource() { Text = "Item1", IsExpanded = true };
            var item11 = new TreeSource() { Text = "Item1-1", IsExpanded = true };
            var item12 = new TreeSource() { Text = "Item1-2", IsExpanded = true };
            var item2  = new TreeSource() { Text = "Item2", IsExpanded = false };
            var item21 = new TreeSource() { Text = "Item2-1", IsExpanded = true };
            TreeRoot.Add(item1);
            TreeRoot.Add(item2);
            item1.Add(item11);
            item1.Add(item12);
            item2.Add(item21);

            DataContext = this;
        }
    }



コメント