[WPF] TreeView 範例

  • 4508
  • 0

TreeView Binding 的範例:

這個範例有安裝 MVVM Light,可從Visual Studio擴充功能安裝 

xaml:

<Window x:Class="TreeViewExample.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:ignore="http://www.galasoft.ch/ignore"
        mc:Ignorable="d ignore"
        Height="300"
        Width="300"
        Title="TreeViewExample"
        DataContext="{Binding Main, Source={StaticResource Locator}}">
    
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Skins/MainSkin.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>

    <Grid x:Name="LayoutRoot">

        <TreeView ItemsSource="{Binding MyNodeList}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding MyNodes}">
                    <Button Content="{Binding Name}"/>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}">
                    <Setter Property="IsExpanded" Value="True"/>
                </Style>
            </TreeView.ItemContainerStyle>
        </TreeView>

    </Grid>
</Window>

MainViewModel.cs:

using GalaSoft.MvvmLight;
using System.Collections.Generic;
using TreeViewExample.Model;
using System.Linq;

namespace TreeViewExample.ViewModel
{
    public class MainViewModel : ViewModelBase
    {
        private IList<MyNodeViewModel> _myNodeList;
        
        public IList<MyNodeViewModel> MyNodeList
        {
            get
            {
                return _myNodeList;
            }
            set
            {
                Set(() => MyNodeList, ref _myNodeList, value);
            }
        }

        public MainViewModel()
        {
            if (!IsInDesignMode)
            {
                // 建立三層的範例資料
                var list = Enumerable.Range(1, 5).Select(n => new MyNodeViewModel { Name = n.ToString() }).ToList();
                foreach (var item in list)
                {
                    item.MyNodes = Enumerable.Range(1, 5).Select(n => new MyNodeViewModel { Name = item.Name + n.ToString() }).ToList();

                    foreach (var item2 in item.MyNodes)
                    {
                        item2.MyNodes = Enumerable.Range(1, 5).Select(n => new MyNodeViewModel { Name = item2.Name + n.ToString() }).ToList();
                    }
                }
                MyNodeList = list;
            }
        }

    }
}

MyNodeViewModel.cs:

using GalaSoft.MvvmLight;
using System.Collections.Generic;

namespace TreeViewExample.Model
{
    public class MyNodeViewModel : ObservableObject
    {
        private string _name;

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                Set(() => Name, ref _name, value);
            }
        }

        
        private IList<MyNodeViewModel> _myNodes ;
        
        public IList<MyNodeViewModel> MyNodes
        {
            get
            {
                return _myNodes;
            }
            set
            {
                Set(()=> MyNodes, ref _myNodes, value);
            }
        }
    }
}

這是個什麼樣的範例?

 示範如何建立一個具有子節點的類別(MyNodeViewModel.cs),並將內容Binding至TreeView上,最後顯示樹狀階層的範例。


Xaml 中的 TreeView 應該要注意的點?

TreeView 的 ItemsSource 屬性是需要 Binding 一個集合的物件,所以範例中使用 MyNodeList 來做 Binding。

TreeView.ItemTemplate 表示要套用的項目樣板,這裡使用HierarchicalDataTemplate,表示階層式的資料樣板。

HierarchicalDataTemplate 的 ItemsSource  屬性是子節點集合的物件,像範例中會不斷的列出 MyNodes 每一個物件,

繼續往每個子節點的 MyNodes列出,直到沒有項目,就會形成樹狀。

Button 是 HierarchicalDataTemplate  的資料樣板,可以任意放入自己想顯示的控制項。

TreeView.ItemContainerStyle 能控制這些樹狀的每個項目,應該如何顯示,例如可以預設展開(IsExpanded)每個節點。


這裡所顯示的資料,是在MainViewModel的建構式初始化來的,實際上應該要替換成你想如何顯示的資料
 擁有子節點的類別,不一定要命名MyNodes,只要能定義屬性是集合的節點,就能讓HierarchicalDataTemplate顯示所有階層

 

以上。