WPF之层级数据模板HierarchicalDataTemplate的使用

WPF之层级数据模板HierarchicalDataTemplate的使用

  • 1、HierarchicalDataTemplate + List
  • 2、HierarchicalDataTemplate + XML
  • 3、TreeView + HierarchicalDataTemplate + ObservableCollection

HierarchicalDataTemplate是能够帮助层级控件显示层级数据的模板,一般多用于MenuItem和TreeViewItem,也可自己实现层级数据结构。

1、HierarchicalDataTemplate + List

数据:

using System.Collections.Generic;
 
namespace CSDNWpfApp.com.data
{
    //公司数据
    public class CompanyData
    {
        public string Name { get; set; }
        public List<DempartmentData> DempartmentDatas { get; set; }
    }
 
    //部门数据
    public class DempartmentData
    {
        public string Name { get; set; }
        public List<EmployeeData> EmployeeDatas { get; set; }
    }
 
    //员工
    public class EmployeeData
    {
        public string Name { get; set; }
    }
 
}

界面:

<Window x:Class="CSDNWpfApp.TreeViewWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CSDNWpfApp" xmlns:da="clr-namespace:CSDNWpfApp.com.data"
        mc:Ignorable="d"
        Title="TreeViewWindow" Height="450" Width="800">
    <Window.Resources>
        
        <HierarchicalDataTemplate DataType="{x:Type da:CompanyData}" ItemsSource="{Binding Path=DempartmentDatas}">
            <TextBlock Text="{Binding Name}"/>
        HierarchicalDataTemplate>
        
        <HierarchicalDataTemplate DataType="{x:Type da:DempartmentData}" ItemsSource="{Binding Path=EmployeeDatas}">
            <TextBlock Text="{Binding Name}"/>
        HierarchicalDataTemplate>
        
        <HierarchicalDataTemplate DataType="{x:Type da:EmployeeData}">
            <TextBlock Text="{Binding Name}"/>
        HierarchicalDataTemplate>
        
    Window.Resources>
    <Grid>
        <TreeView x:Name="treeView" HorizontalAlignment="Left" Height="350" Margin="30,30,0,0" VerticalAlignment="Top" Width="440"/>
        <Button x:Name="button" Content="测试" HorizontalAlignment="Left" Margin="575,61,0,0" VerticalAlignment="Top" Width="105" Height="69" Click="Button_Click"/>
 
    Grid>
Window>

说明:

  • 引用了数据类的名称空间 xmlns:da=“clr-namespace:CSDNWpfApp.com.data”
  • DataType指定了HierarchicalDataTemplate模板用哪种数据类型
  • ItemsSource指定下一层显示哪些数据
  • 内容指定了一个TextBlock,并绑定了需要显示当前指定类型数据中的属性

2、HierarchicalDataTemplate + XML

数据


<root>
 
  <Company Name="公司1">
    <Dempartment Name="部门1">
      <Employee Name="员工1"/>
      <Employee Name="员工2"/>
    Dempartment>
    <Dempartment Name="部门2">
      <Employee Name="员工1"/>
      <Employee Name="员工2"/>
    Dempartment>
  Company>
 
  <Company Name="公司2">
    <Dempartment Name="部门1">
      <Employee Name="员工1"/>
      <Employee Name="员工2"/>
    Dempartment>
    <Dempartment Name="部门2">
      <Employee Name="员工1"/>
      <Employee Name="员工2"/>
    Dempartment>
  Company>
  
root>

界面

<Window x:Class="CSDNWpfApp.TreeViewWindow2"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CSDNWpfApp"
        mc:Ignorable="d"
        Title="TreeViewWindow2" Height="450" Width="800">
    <Window.Resources>
        <XmlDataProvider x:Key="xdp" Source="Companys.xml" XPath="root/Company"/>
 
        <HierarchicalDataTemplate DataType="Company" ItemsSource="{Binding XPath=Dempartment}">
            <TextBlock Text="{Binding XPath=@Name}"/>
        HierarchicalDataTemplate>
 
        <HierarchicalDataTemplate DataType="Dempartment" ItemsSource="{Binding XPath=Employee}">
            <TextBlock Text="{Binding XPath=@Name}"/>
        HierarchicalDataTemplate>
 
        <HierarchicalDataTemplate DataType="Employee">
            <TextBlock Text="{Binding XPath=@Name}"/>
        HierarchicalDataTemplate>
        
    Window.Resources>
    <Grid>
        <TreeView x:Name="treeView" ItemsSource="{Binding Source={StaticResource xdp}}" HorizontalAlignment="Left" Height="350" Margin="30,30,0,0" VerticalAlignment="Top" Width="440"/>
    Grid>
Window>

说明

  • 使用XmlDataProvider作为数据源
  • DataType 可以把xml数据中的元素作为当前数据类型,这样元素的子节点和Attribute可以使用XPath来访问
  • ItemsSource 通过XPath指定下一级需要显示的元素
  • 显示内容指定了一个TextBlock 通过XPath绑定当前数据类型需要显示的属性

3、TreeView + HierarchicalDataTemplate + ObservableCollection

上面两个例子均为学习过程中所需要的Demo,在《深入浅出WPF》的第11章有类似的Demo,但在具体项目中,HierarchicalDataTemplate常与TreeView 构建层级结构。且常常需要界面显示的数据动态刷新,则会使用到ObservableCollection集合。

具体使用看如下代码。

数据类

/// 
///  数据类
/// 
public class UIWindowsHelper : INotifyPropertyChanged
{
	private ObservableCollection<Project> _projects = new ObservableCollection<Project>();
	public ObservableCollection<Project> Projects
    {
         get { return _projects; }
         set
         {
             if (_projects == value)
                 return;
             _projects = value;
             OnPropertyChanged("Projects");
         }
     }
	
	//......
}

/// 
///  Project类
/// 
public class Project : ICloneable
{
	
    private string _projectName = "";
    public string ProjectName
    {
          get { return _projectName; }
          set
          {
              if (_projectName != value)
              {
                  _projectName = value;
                  OnPropertyChanged("ProjectName");
              }
          }
      }

	private ObservableCollection<SubProject> _listSubProjects = new ObservableCollection<SubProject>();
	public ObservableCollection<SubProject> ListSubProjects
    {
          get { return _listSubProjects; }
          set
          {
              _listSubProjects = value;
              OnPropertyChanged("ListSubProjects");
          }
      }
		
	//......
}

/// 
///  SubProject类
/// 
public class Project : ICloneable
{
	private string _subProjectName;
    public string subProjectName
      {
          get { return _subProjectName; }
          set {
              _subProjectName = value;
              OnPropertyChanged("subProjectName");

          }
      }
		
	//......
}

界面

<TreeView x:Name="ProjectsTreeView"  ItemsSource="{Binding Projects,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"  BorderThickness="1,0,1,1" BorderBrush="#EEEEEE" AllowDrop="True" >       
<TreeView.ItemTemplate>
    <HierarchicalDataTemplate ItemsSource="{Binding ListSubProjects, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
        <StackPanel x:Name="myBorder">
            <Label Content="{Binding ProjectName,Mode=TwoWay}" />
        StackPanel>
        <HierarchicalDataTemplate.ItemContainerStyle>
            <Style TargetType="{x:Type TreeViewItem}">
                {Binding IsSelected,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                
                
                    
                        {x:Type TreeViewItem}">
                                Binding subProjectName,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                            
                            
                                "IsSelected" Value="True">
                                    "Foreground" TargetName="myLabel" Value="#f75d00">
                                
                            
                        
                    
                
            Style>
        HierarchicalDataTemplate.ItemContainerStyle>
    HierarchicalDataTemplate>
TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
    <Style TargetType="{x:Type TreeViewItem}">
        "IsExpanded" Value="True"/>
    Style>
TreeView.ItemContainerStyle>
TreeView>

设置数据绑定到界面的方法有多种可以实现,如在*.xaml.cs文件中,设置this.DataContext。

你可能感兴趣的:(WPF,wpf)