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 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM