在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