C#WPFでTreeViewの使い方を分かりやすく解説

イラスト XAML

C#WPFにて、TreeViewを作成します。TreeViewの作成方法は、静的に直接XAMLに書き込む方法、C#コード側からバインドさせる方法、ViewModelっぽく、XAMLからVMを指定する方法の3つを解説してみました。

コードを追って、そのままコピペすれば動くように記事を書いてあります。

TreeをXAMLから静的に設定

VisualStudioからWPFアプリを作成します。

参考 TreeView の概要

Microsoftのドキュメントより、XAMLをコピペします。

作成されたTreeViewソリューションの、MainWindow.xaml のデザイン部分 XAMLに貼り付けました。元々作成されたGridの間に以下をコピペするだけで静的なTreeViewは完成です。

<TreeView Name="myTreeViewEvent" >
  <TreeViewItem Header="Employee1" IsSelected="True">
    <TreeViewItem Header="Jesper Aaberg"/>
    <TreeViewItem Header="Employee Number">
      <TreeViewItem Header="12345"/>
    </TreeViewItem>
    <TreeViewItem Header="Work Days">
      <TreeViewItem Header="Monday"/>
      <TreeViewItem Header="Tuesday"/>
      <TreeViewItem Header="Thursday"/>
    </TreeViewItem>
  </TreeViewItem>
  <TreeViewItem Header="Employee2">
    <TreeViewItem Header="Dominik Paiha"/>
    <TreeViewItem Header="Employee Number">
      <TreeViewItem Header="98765"/>
    </TreeViewItem>
    <TreeViewItem Header="Work Days">
      <TreeViewItem Header="Tuesday"/>
      <TreeViewItem Header="Wednesday"/>
      <TreeViewItem Header="Friday"/>
    </TreeViewItem>
  </TreeViewItem>
</TreeView>

このコードを、作成した、TestTreeviewの MainWindowにコピペします

<Window x:Class="TestTree.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:TestTree"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TreeView Name="myTreeViewEvent" >
            <TreeViewItem Header="Employee1" IsSelected="True">
                <TreeViewItem Header="Jesper Aaberg"/>
                <TreeViewItem Header="Employee Number">
                    <TreeViewItem Header="12345"/>
                </TreeViewItem>
                <TreeViewItem Header="Work Days">
                    <TreeViewItem Header="Monday"/>
                    <TreeViewItem Header="Tuesday"/>
                    <TreeViewItem Header="Thursday"/>
                </TreeViewItem>
            </TreeViewItem>
            <TreeViewItem Header="Employee2">
                <TreeViewItem Header="Dominik Paiha"/>
                <TreeViewItem Header="Employee Number">
                    <TreeViewItem Header="98765"/>
                </TreeViewItem>
                <TreeViewItem Header="Work Days">
                    <TreeViewItem Header="Tuesday"/>
                    <TreeViewItem Header="Wednesday"/>
                    <TreeViewItem Header="Friday"/>
                </TreeViewItem>
            </TreeViewItem>
        </TreeView>
    </Grid>
</Window>

すると、こんな感じです。デザイン画面でもTreeViewが配置されている事が分かります。

実行すると、TreeViewが動きます。

チェックボックスを入れる

静的なTreeViewに、チェックボックスを入れてみます。

<TreeViewItem>
  <TreeViewItem.Header>
    <DockPanel>
      <CheckBox/>
      <TextBlock>
        TreeViewItem Text
      </TextBlock>
    </DockPanel>
  </TreeViewItem.Header>
</TreeViewItem>

チェックボックスを入れると、こんな感じになります。

C#からバインドさせ動的に設定する

Animalクラスを作成します

Modelを作成していきます c#のクラスです

Animalクラスを、さらにChildとして、自分自身に設定しているのがミソです

namespace TestTree.Model
{
    public class Animal
    {
        public string Name { get; set; }
        public List<Animal> Child { get; set; }
    }
}

MainWindowでプロパティをバインドさせます

using TestTree.Model;

namespace TestTree
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public List<Animal> _Animal { get; set; }

        public MainWindow()
        {
            InitializeComponent();

            //プロパティを生成
            _Animal = new List<Animal>()
            {
                new Animal()
                {
                    Name = "Animal1",
                    Child = new List<Animal>()
                    {
                        new Animal() { Name = "Ani11" },
                        new Animal() { Name = "Ani12" },
                        new Animal() { Name = "Ani13" },
                    }
                },
                new Animal()
                {
                    Name = "Animal2",
                    Child = new List<Animal>()
                    {
                        new Animal() { Name = "Ani21" },
                        new Animal()
                        {
                            Name = "Ani22",
                            Child = new List<Animal>()
                            {
                                new Animal() { Name = "Ani221" },
                                new Animal() { Name = "Ani222" }
                            }
                        }
                    }
                }
            };

            //プロパティをItemSourceにバインドさせる
            TreeViewAni.ItemsSource = _Animal;
        }
    }
}

XAMLを準備します

HierarchicalDataTemplate を利用する事で他のリストを含むリスト データを簡単に表示する事ができます。

<Window x:Class="TestTree.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:TestTree"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <TreeView x:Name="TreeViewAni">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate DataType= "local:Animal" ItemsSource="{Binding Child}">
                    <TextBlock Text="{Binding Name}"/>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</Window>

実行すると動的にC#で生成したプロパティを表示する事ができます。

MVVMっぽく書いてみる

動的にバインドさせる方法として、MVVMっぽく書いてみるとこんな感じになります。上記で直接MainWindow.xaml.csに書いたコードをVMのクラスに書き直します。

Animalクラスは変わりません

namespace TestTree.Model
{
    public class Animal
    {
        public string Name { get; set; }
        public List<Animal> Child { get; set; }
    }
}

VM_Animal ViewModelを作成します

using TestTree.Model;

namespace TestTree
{
    public class VM_Animal
    {
        public List<Animal> _VMAnimal { get; set; }

        public VM_Animal()
        {
            //プロパティを生成
            _VMAnimal = new List<Animal>()
            {
                new Animal()
                {
                    Name = "Animal1",
                    Child = new List<Animal>()
                    {
                        new Animal() { Name = "Ani11" },
                        new Animal() { Name = "Ani12" },
                        new Animal() { Name = "Ani13" },
                    }
                },
                new Animal()
                {
                    Name = "Animal2",
                    Child = new List<Animal>()
                    {
                        new Animal() { Name = "Ani21" },
                        new Animal()
                        {
                            Name = "Ani22",
                            Child = new List<Animal>()
                            {
                                new Animal() { Name = "Ani221" },
                                new Animal() { Name = "Ani222" }
                            }
                        }
                    }
                }
            };

        }
    }
}

これをXAML側でバインドさせます

<Window x:Class="TestTree.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:TestTree"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.DataContext>
        <local:VM_Animal />
    </Window.DataContext>
    
    <Grid>
        <TreeView x:Name="TreeViewAniVM" ItemsSource="{Binding _VMAnimal }">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate DataType= "local:Animal" ItemsSource="{Binding Child}">
                    <TextBlock Text="{Binding Name}"/>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</Window>

実際に表示させるMainWindow.xaml.csでは何もする必要がなくなります。

ポイント XAMLで、Window.DataContext に、作成したViewModelを指定しています。

動的にTreeViewの中にCheckBoxを生成する

上記のコードまでできていたら、CheckBoxに変更するのはとても簡単です。XAML上で

<TextBlock Text=”{Binding Name}”/>

<CheckBox Content=”{Binding Name}”/>

と書き換えるだけです。

ViewModelっぽく書いた上記例の、XAMLだけ以下のように変更しました。

<Window x:Class="TestTree.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:TestTree"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.DataContext>
        <local:VM_Animal />
    </Window.DataContext>
    
    <Grid>
        <TreeView x:Name="TreeViewAniVM" ItemsSource="{Binding _VMAnimal }">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate DataType= "local:Animal" ItemsSource="{Binding Child}">
                    <CheckBox Content="{Binding Name}"/>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </Grid>
</Window>

実行すると、さきほどTextBlockだったものがCheckBoxに変わっています。

コメント

タイトルとURLをコピーしました