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

  • 相关阅读:
    无法加载 DLL“librdkafka”: 找不到指定的模块。 (异常来自 HRESULT:0x8007007E)
    C#编码规范
    requests(五)
    python-requests(四):调用上传文件的接口的解决方案
    静态代码扫描工具
    推荐一款 python 管理工具:anaconda
    selenium 网页自动化-在访问一个网页时弹出的浏览器窗口,我该如何处理?
    静态代码扫描工具
    静态代码扫描工具
    静态代码扫描工具
  • 原文地址:https://www.cnblogs.com/goldren/p/2812697.html
Copyright © 2020-2023  润新知