HierarchicalDataTemplate顧名思義,分層數據模板,就是用來定義分層數據樣式的模板,一般多用於MenuItem和TreeViewItem
包含幾個重要屬性
DataType指定模板用於哪種數據類型
ItemsSource指定該類數據的子集,即下一層顯示那些數據
內容 指定數據如何顯示 綁定哪個屬性
MSDN上的一個例子:
1.定義數據集
public class League { public League(string name) { _name = name; _divisions = new List<Division>(); } string _name; public string Name { get { return _name; } } List<Division> _divisions; public List<Division> Divisions { get { return _divisions; } } } public class Division { public Division(string name) { _name = name; _teams = new List<Team>(); } string _name; public string Name { get { return _name; } } List<Team> _teams; public List<Team> Teams { get { return _teams; } } } public class Team { public Team(string name) { _name = name; } string _name; public string Name { get { return _name; } } } public class ListLeagueList : List<League> { public ListLeagueList() { League l; Division d; Add(l = new League("League A")); l.Divisions.Add((d = new Division("Division A"))); d.Teams.Add(new Team("Team I")); d.Teams.Add(new Team("Team II")); d.Teams.Add(new Team("Team III")); d.Teams.Add(new Team("Team IV")); d.Teams.Add(new Team("Team V")); l.Divisions.Add((d = new Division("Division B"))); d.Teams.Add(new Team("Team Blue")); d.Teams.Add(new Team("Team Red")); d.Teams.Add(new Team("Team Yellow")); d.Teams.Add(new Team("Team Green")); d.Teams.Add(new Team("Team Orange")); l.Divisions.Add((d = new Division("Division C"))); d.Teams.Add(new Team("Team East")); d.Teams.Add(new Team("Team West")); d.Teams.Add(new Team("Team North")); d.Teams.Add(new Team("Team South")); Add(l = new League("League B")); l.Divisions.Add((d = new Division("Division A"))); d.Teams.Add(new Team("Team 1")); d.Teams.Add(new Team("Team 2")); d.Teams.Add(new Team("Team 3")); d.Teams.Add(new Team("Team 4")); d.Teams.Add(new Team("Team 5")); l.Divisions.Add((d = new Division("Division B"))); d.Teams.Add(new Team("Team Diamond")); d.Teams.Add(new Team("Team Heart")); d.Teams.Add(new Team("Team Club")); d.Teams.Add(new Team("Team Spade")); l.Divisions.Add((d = new Division("Division C"))); d.Teams.Add(new Team("Team Alpha")); d.Teams.Add(new Team("Team Beta")); d.Teams.Add(new Team("Team Gamma")); d.Teams.Add(new Team("Team Delta")); d.Teams.Add(new Team("Team Epsilon")); } public League this[string name] { get { foreach (League l in this) if (l.Name == name) return l; return null; } } }
2.窗體
<!--<SnippetHDT>--> <Window x:Class="SDKSample.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="HierarchicalDataTemplate Sample" xmlns:src="clr-namespace:SDKSample"> <DockPanel> <DockPanel.Resources> <src:ListLeagueList x:Key="MyList"/> <HierarchicalDataTemplate DataType = "{x:Type src:League}" ItemsSource = "{Binding Path=Divisions}"> <TextBlock Text="{Binding Path=Name}"/> </HierarchicalDataTemplate> <HierarchicalDataTemplate DataType = "{x:Type src:Division}" ItemsSource = "{Binding Path=Teams}"> <TextBlock Text="{Binding Path=Name}"/> </HierarchicalDataTemplate> <DataTemplate DataType="{x:Type src:Team}"> <TextBlock Text="{Binding Path=Name}"/> </DataTemplate> </DockPanel.Resources> <Menu Name="menu1" DockPanel.Dock="Top" Margin="10,10,10,10"> <MenuItem Header="My Soccer Leagues" ItemsSource="{Binding Source={StaticResource MyList}}" /> </Menu> <TreeView> <TreeViewItem ItemsSource="{Binding Source={StaticResource MyList}}" Header="My Soccer Leagues" /> </TreeView> </DockPanel> </Window>
這個例子的數據源是一個分層的List對象,下面一個例子的數據源是一個XML文件,大體相同,不同的地方是需要先實例化一個XmlDataProvider用來獲取XML的內容,綁定的時候用的不是Path,而是XPath屬性,給控件綁定屬性的時候屬性名加@(加@的是屬性Attribute 不加的是子級元素)
1.XML文件
<?xml version="1.0" encoding="utf-8" ?> <Data xmlns=""> <Grade Name="初一"> <Class Name="1班"> <Group Name="1-1-1組"></Group> <Group Name="1-1-2組"></Group> <Group Name="1-1-3組"></Group> </Class> <Class Name="2班"> <Group Name="1-2-1組"></Group> <Group Name="1-2-2組"></Group> <Group Name="1-2-3組"></Group> </Class> <Class Name="3班"> <Group Name="1-3-1組"></Group> <Group Name="1-3-2組"></Group> <Group Name="1-3-3組"></Group> </Class> </Grade> <Grade Name="初二"> <Class Name="21班"> <Group Name="2-1-1組"></Group> <Group Name="2-1-2組"></Group> <Group Name="2-1-3組"></Group> </Class> <Class Name="22班"> <Group Name="2-2-1組"></Group> <Group Name="2-2-2組"></Group> <Group Name="2-2-3組"></Group> </Class> <Class Name="23班"> <Group Name="2-3-1組"></Group> <Group Name="2-3-2組"></Group> <Group Name="2-3-3組"></Group> </Class> </Grade> <Grade Name="初三"> <Class Name="31班"> <Group Name="3-1-1組"></Group> <Group Name="3-1-2組"></Group> <Group Name="3-1-3組"></Group> </Class> <Class Name="32班"> <Group Name="3-2-1組"></Group> <Group Name="3-2-2組"></Group> <Group Name="3-2-3組"></Group> </Class> <Class Name="33班"> <Group Name="3-3-1組"></Group> <Group Name="3-3-2組"></Group> <Group Name="3-3-3組"></Group> </Class> </Grade> </Data>
2.分層模板
<XmlDataProvider x:Key="Data2" Source="Data.xml" XPath="Data/Grade"/> <HierarchicalDataTemplate DataType="Grade" ItemsSource="{Binding XPath= Class}"> <TextBlock Text="{Binding XPath=@Name}"/> </HierarchicalDataTemplate> <HierarchicalDataTemplate DataType="Class" ItemsSource="{Binding XPath=Group}"> <RadioButton Content="{Binding XPath=@Name}" GroupName="gr"/> </HierarchicalDataTemplate> <HierarchicalDataTemplate DataType="Group" ItemsSource="{Binding XPath=Student}"> <CheckBox Content="{Binding XPath=@Name}"/> </HierarchicalDataTemplate>
3.使用模板
<TreeView Margin="5" ItemsSource="{Binding Source={StaticResource Data2}}"></TreeView>
也試過遞歸方式給TreeView添加節點
View Code
void LoadXmlToTree(XElement root,TreeViewItem item) { if (root != null) { foreach (XElement xe in root.Elements()) { TreeViewItem item2 = new TreeViewItem(); item2.Header = xe.Attribute("Name").Value.ToString(); item.Items.Add(item2); LoadXmlToTree(xe,item2); } } }
明顯不如模板使用起來方便,但是現在的理解還處於初級階段,只是簡單的套使用方法,知其然,不知其所以然,還有待更進一步的理解,畢竟真正理解透了,原理清楚了,才能更靈活的應用。
注:Dictionary類型的需要用values屬性
參考 MSDN 《深入淺出WPF》第11章
