最近在学习wpf,习惯把自己学习的东西记下来。

  刚开始接触的这个控件,有点不知道怎么用。网上看了下,好像大家都觉得不如winform里面的好使。反正,我以前是用mfc做界面的,对c#不熟。网上看了几个例子,自己动手做了一下,现在把大概步骤记录下来。我这里比较简单,没有用什么模式。网上有一篇《使用ViewModel模式来简化WPF的TreeView》大家可以看看。

  一、一个简单的树

  首先、定义一个树节点的类,用来保存树节点信息:

  TreeItem.cs文件:

  using System;

  using System.Collections.Generic;

  using System.Linq;

  using System.Text;

  using System.Collections.ObjectModel;

  namespace WPFTreeviewExamples

  {

  class TreeItem

  {

  // 构造函数

  public TreeItem()

  {

  children= new ObservableCollection();

  }

  //////////////////////////////////////////////////////////////////////////

  // 节点文字信息

  public stringtext

  {

  get;

  set;

  }

  // 节点其他信息

  // ...

  // 父节点

  public TreeItemparent

  {

  get;

  set;

  }

  // 子节点

  public ObservableCollection children

  {

  get;

  set;

  }

  //////////////////////////////////////////////////////////////////////////

  }

  }

  然后、在xaml文件中定义树的属性样式:

<TreeView Name="treeViewSimple" >

            <TreeView.ItemContainerStyle>

                <Style TargetType="{x:TypeTreeViewItem}">

                    <Setter Property="IsExpanded" Value="true"/>

                </Style>

            </TreeView.ItemContainerStyle>

            <TreeView.Resources>

                <HierarchicalDataTemplate DataType="{x:Type local:TreeItem}"  ItemsSource="{Binding Path=children}">

                    <StackPanel Orientation="Horizontal" Margin="0,2,0,2">                       

                        <TextBlock Text="{Binding text}" ToolTip="{Binding text}"/>

                    </StackPanel>

                </HierarchicalDataTemplate>                

            </TreeView.Resources>

        </TreeView>

  其中:<Setter Property="IsExpanded" Value="true"/>表示所有节点都展开。

  HierarchicalDataTemplate定义节点样式。DataType="{x:Typelocal:TreeItem}用来表明存储节点数据的类是什么。

  二、带图标的树

  很简单,只要添加图标相关信息即可:

  TreeItem.cs文件:

//////////////////////////////////////////////////////////////////////////

       // 节点文字信息

       public stringtext

       {

            get;

            set;

       }

       // 节点图标路径

       public stringitemIcon

       {

            get;

            set;

       }

       // 节点其他信息

        // ...

  xaml文件

<TreeView.Resources>

                <HierarchicalDataTemplate DataType="{x:Type local:TreeItem}"  ItemsSource="{Binding Path=children}">

                    <StackPanel Orientation="Horizontal" Margin="0,2,0,2">  

                        <Image VerticalAlignment="Center" Source="{Binding itemIcon}" ></Image>

                        <TextBlock VerticalAlignment="Center" Text="{Binding text}" ToolTip="{Binding text}"/>

                    </StackPanel>

                </HierarchicalDataTemplate>                

            </TreeView.Resources>

  三、更多功能的树

  1、 首先,让我加一个checkbox

  这需要完善 TreeItem:

  让它继承与INotifyPropertyChanged 接口,以便通知checkbox状态改变:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Collections.ObjectModel;

using System.ComponentModel;

namespace WPFTreeviewExamples

{

   class TreeItem: INotifyPropertyChanged

   {

       // 构造函数

       public TreeItem()

       {

            children= new ObservableCollection<TreeItem>();

       }
       //////////////////////////////////////////////////////////////////////////

       // 节点文字信息

       public stringtext

       {

            get;

            set;

       }

       // 节点图标路径

       public stringitemIcon

       {

            get;

            set;

       }

       // 节点其他信息

       // ...
       // 父节点

       public TreeItemparent

       {

            get;

            set;

       }

       // 子节点

       public ObservableCollection<TreeItem> children

       {

            get;

            set;

       }

       //////////////////////////////////////////////////////////////////////////
       ////////   Check 相关信息  ///////////////////////////////////////////

       bool? _isChecked= false;
       public bool?IsChecked

       {

            getreturn _isChecked;}

            setthis.SetIsChecked(valuetruetrue); }

       }
       void SetIsChecked(boolvaluebool updateChildren,bool updateParent)

       {

            if(value == _isChecked)

                return;

             _isChecked= value;

             if(updateChildren && _isChecked.HasValue)

            {

                foreach(TreeItem childin children)

                {

                    child.SetIsChecked(_isChecked,truefalse);

                }

            }

             if(updateParent && parent != null)

            {

                parent.VerifyCheckState();

            }

             this.OnPropertyChanged("IsChecked");

       }

       void VerifyCheckState()

       {

            bool?state = null;

            for(int i = 0; i < this.children.Count;++i)

            {

                bool? current = this.children[i].IsChecked;

                if(i == 0)

                {

                    state= current;

                }

                elseif (state !=current)

                {

                    state= null;

                    break;

                }

            }

            this.SetIsChecked(state,falsetrue);

       }

       ////////////////////////////////////////////////////////////////////////////

       void OnPropertyChanged(string prop)

       {

            if(this.PropertyChanged!= null)

                this.PropertyChanged(this,new PropertyChangedEventArgs(prop));

       }

 

       public eventPropertyChangedEventHandler PropertyChanged; 

       //////////////////////////////////////////////////////////////////////////

   }

}
<TreeView.Resources>

                <HierarchicalDataTemplate DataType="{x:Type local:TreeItem}"  ItemsSource="{Binding Path=children}">

                    <StackPanel Orientation="Horizontal" Margin="0,2,0,2">  

                        <CheckBox Focusable="False" IsChecked="{Binding IsChecked,Mode=TwoWay}"VerticalAlignment="Center" />

                        <Image VerticalAlignment="Center" Source="{Binding itemIcon}" ></Image>

                        <TextBlock VerticalAlignment="Center" Text="{Binding text}" ToolTip="{Binding text}"/>

                    </StackPanel>

                </HierarchicalDataTemplate>                

            </TreeView.Resources>
  void InitTree()

  {

  tree= new TreeItem();

  // 添加一级顶层子节点

  TreeItemroot = new TreeItem();

  root.text = "根节点";

  root.itemIcon = "./image/root.png";

  // 把根节点加进来

  tree.children.Add(root);

  root.parent = tree;

  // 给根节点加一些子节点

  TreeItemhubei = new TreeItem();

  hubei.text = "湖北";

  hubei.itemIcon = "./image/Provine.png";

  root.children.Add(hubei);

  hubei.parent = root;

  // 给湖北下加几个城市

  TreeItemwuhan = new TreeItem();

  wuhan.text = "武汉";

  wuhan.itemIcon = "./image/City.png";

  TreeItemxiaogan = newTreeItem();

  xiaogan.text = "孝感";

  xiaogan.itemIcon = "./image/City.png";

  TreeItemxiangyang = newTreeItem();

  xiangyang.text = "襄阳";

  xiangyang.itemIcon = "./image/City.png";

  hubei.children.Add(wuhan);

  wuhan.parent = hubei;

  hubei.children.Add(xiaogan);

  xiaogan.parent = hubei;

  hubei.children.Add(xiangyang);

  xiangyang.parent = hubei;

  // 给根节点加一些子节点

  TreeItemfamily = newTreeItem();

  family.text = "我的家";

  family.itemIcon = "./image/Provine.png";

  root.children.Add(family);

  family.parent = root;

  // 给湖北下加几个城市

  TreeItemdad = new TreeItem();

  dad.text = "爸爸";

  dad.itemIcon = "./image/City.png";

  TreeItemmom = new TreeItem();

  mom.text = "妈妈";

  mom.itemIcon = "./image/City.png";

  TreeItemme = new TreeItem();

  me.text = "我";

  me.itemIcon = "./image/City.png";

  TreeItembrother = newTreeItem();

  brother.text = "弟弟";

  brother.itemIcon = "./image/City.png";

  family.children.Add(dad);

  dad.parent = family;

  family.children.Add(mom);

  mom.parent = family;

  family.children.Add(me);

  me.parent = family;

  family.children.Add(brother);

  brother.parent = family;

  // 把数据绑定到控件

  treeViewMine.ItemsSource = tree.children;

  }