WPF自定义TreeView显示结构通用类

  在WPF中,专门有HierarchicalDataTemplate用于自定义显示TreeView和ListBox的层次结构,结合后台定义的数据,得以实现五花八门的外观。我现在先简要说明一下HierarchicalDataTemplate的使用方式: 

1 public class DataItem
2 {
3     public string Header { get; set; }
4     public IList<DataItem> Childs { get; set; }
5 }

  上面是树的一个结点类,包括了一个Header字段和子结点列表,下面则是对应的前台代码:

<Grid>
     <Grid.Resources>
     <HierarchicalDataTemplate x:Key="myDataTemplate" ItemsSource="{Binding Childs}">
       <Label Content="{Binding Header}" />
     </HierarchicalDataTemplate>
   </Grid.Resources>
   <TreeView x:Name="TV_Test" ItemTemplate="{StaticResource myDataTemplate}" />
</Grid>

  注意到,HierarchicalDataTemplate的ItemsSource就是层叠显示的关键,它可以遍历对应数据的所有Childs字段,并显示成<Label ... />的形式。接下来,把DataItem类型的数据集合赋给TreeView控件的ItemSource就完成了树形结构的显示:

1 List<DataItem> dataList = new List<DataItem>();
2 DataItem item1 = new DataItem { Header = "结点1" };
3 item1.Childs = new List<DataItem>();
4 item1.Childs.Add(new DataItem { Header = "结点1-1" });
5 item1.Childs.Add(new DataItem { Header = "结点1-2" });
6 dataList.Add(item1);
7 dataList.Add(new DataItem { Header = "结点2" });
8 TV_Test.ItemsSource = dataList;

  所得结果如下图所示:

  上面只是一个简单的示例,实际上可以通过更改HierarchicalDataTemplate中的内容来自定义树形显示,如图片、颜色、大小、布局等等。为了使上面的数据类DataItem更为通用 ,我自己扩充了一个结点类,使用该类,基本就可以完成大部分的功能了。

通用树结点类
  1 using System.Collections.Generic;
  2 using System.Collections.ObjectModel;
  3 using System.Linq;
  4 
  5 namespace EntityFramework.Common
  6 {
  7     /// <summary>
  8     /// 实现了INotifyPropertyChanged接口通知的轻量级基类
  9     /// </summary>
 10     public abstract class ObservableBase : INotifyPropertyChanged
 11     {
 12         public event PropertyChangedEventHandler PropertyChanged;
 13 
 14         protected void RaisePropertyChanged(string propertyName)
 15         {
 16             if (PropertyChanged != null)
 17             {
 18                 PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
 19             }
 20         }
 21     }
 22 
 23     /// <summary>
 24     /// 树数据类
 25     /// </summary>
 26     public class TreeViewData : ObservableBase
 27     {
 28         #region 私有字段
 29 
 30         private string _Header;
 31         private object _Tag;
 32         private TreeViewData _Parent;
 33         private ObservableCollection<TreeViewData> _Childs = new ObservableCollection<TreeViewData>();
 34 
 35         #endregion
 36 
 37         #region 公有属性
 38 
 39         /// <summary>
 40         /// 名字
 41         /// </summary>
 42         public string Header
 43         {
 44             get { return _Header; }
 45             set { _Header = value; RaisePropertyChanged("Header"); }
 46         }
 47 
 48         /// <summary>
 49         /// 标签
 50         /// </summary>
 51         public object Tag
 52         {
 53             get { return _Tag; }
 54             set { _Tag = value; RaisePropertyChanged("Tag"); }
 55         }
 56 
 57         /// <summary>
 58         /// 父项
 59         /// </summary>
 60         public TreeViewData Parent
 61         {
 62             get { return _Parent; }
 63             set { _Parent = value; RaisePropertyChanged("Parent"); }
 64         }
 65 
 66         /// <summary>
 67         /// 子项
 68         /// </summary>
 69         public ObservableCollection<TreeViewData> Childs
 70         {
 71             get { return _Childs; }
 72             set { _Childs = value; RaisePropertyChanged("Childs"); }
 73         }
 74 
 75         #endregion
 76 
 77         #region 方法函数
 78 
 79         public TreeViewData() { }
 80 
 81         public TreeViewData(string header)
 82         {
 83             _Header = header;
 84         }
 85 
 86         public TreeViewData(string header, object tag, TreeViewData parent = null)
 87         {
 88             _Header = header;
 89             _Tag = tag;
 90             _Parent = parent;
 91         }
 92 
 93         /// <summary>
 94         /// 添加子元素
 95         /// </summary>
 96         /// <param name="childs">子元素</param>
 97         /// <returns>个数</returns>
 98         public void AddChild(TreeViewData child)
 99         {
100             child.Parent = this;
101             _Childs.Add(child);
102         }
103 
104         /// <summary>
105         /// 添加子元素集合
106         /// </summary>
107         /// <param name="childs">子元素</param>
108         /// <returns>个数</returns>
109         public int AddChilds(IEnumerable<TreeViewData> childs)
110         {
111             int nCount = 0;
112             foreach (TreeViewData item in childs)
113             {
114                 AddChild(item); ++nCount;
115             }
116             return nCount;
117         }
118 
119         /// <summary>
120         /// 将指定名称的所有子节点从父元素中移除
121         /// </summary>
122         /// <param name="parent">父元素</param>
123         /// <param name="name">子节点名称</param>
124         public void RemoveChilds(TreeViewData parent, string name)
125         {
126             for (int i = 0; i < parent.Childs.Count; ++i)
127             {
128                 if (parent.Childs[i].Header == name)
129                     parent.Childs.Remove(parent.Childs[i]);
130             }               
131         }
132 
133         public override string ToString()
134         {
135             return _Header;
136         }
137 
138         #endregion
139     }
140 }

  这个类实现了INotifyPropertyChanged接口,能够更好地实现前台数据刷新,并且只初始化得当,还可以直接往上追踪父结点,删除、添加子结点。

  转载请注明原址:http://www.cnblogs.com/lekko/archive/2012/08/28/2660360.html 

原文地址:https://www.cnblogs.com/lekko/p/2660360.html