星空雅梦

WPF之HierarchicalDataTemplate

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;
}
}


}

复制代码
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.窗体

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文件

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.分层模板

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);
}
}
}

明显不如模板使用起来方便,但是现在的理解还处于初级阶段,只是简单的套使用方法,知其然,不知其所以然,还有待更进一步的理解,毕竟真正理解透了,原理清楚了,才能更灵活的应用。

原文地址:https://www.cnblogs.com/LiZhongZhongY/p/10896716.html