我的场景我的TreeView如下所示:
我能够使用HierarchicalDataTemplate将ObservableCollection绑定到Child1 / Child2 /../ Child5。虽然我能够将Child1_Of_Child5添加到Child5 ObservableCollection(在调试模式下看到),但是在UI / Treeview中没有反映出相同。
下面是我的XAML代码:
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type VM:ProjectViewModel}" ItemsSource="{Binding SelectActivityViewModelCollection}">
<StackPanel Orientation="Horizontal">
<Image Source="./resources/New_Package.png" Width="15" Height="15"/>
<TextBlock Text="{Binding Header}"></TextBlock>
</StackPanel>
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type VM:SelectActivityViewModel}" ItemsSource="{Binding ToolsViewModelCollection}"
>
<StackPanel Orientation="Horizontal">
<Image Source="./resources/New_Package.png" Width="15" Height="15"/>
<TextBlock Text="{Binding Header}"></TextBlock>
</StackPanel>
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type VM:ToolsViewModel}" ItemsSource="{Binding SheetsViewModelBaseCollection}">
<StackPanel Orientation="Horizontal">
<Image Source="./resources/New_Package.png" Width="15" Height="15"/>
<TextBlock Text="{Binding Header}"></TextBlock>
</StackPanel>
<HierarchicalDataTemplate.ItemTemplate>
<HierarchicalDataTemplate x:Name="LastLevel" DataType="{x:Type VM:ViewModelBase}" ItemsSource="{Binding FeaturesViewModelCollection}">
<StackPanel Orientation="Horizontal">
<Image Source="./resources/file.png" Width="15" Height="15"/>
<TextBlock Text="{Binding Header}"/>
</StackPanel>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
类结构:( ViewModelBase扩展到所有类)
我试图在示例项目中重现您的问题。
根据您的描述,ToolsViewModel有两个集合(SheetsViewModel和FeaturesViewModel)。如果要在树中显示这两个,则必须创建包含所有这些对象的单个集合。
我创建了一个名为ViewModelCollection的附加集合来展示它是如何工作的。
对于我的测试,我已经定义了类如下:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TreeViewTest
{
class ViewModelBase
{
}
class ViewModel
{
public ObservableCollection<ProjectViewModel> ProjectViewModelCollection { get; private set; }
public ViewModel ( )
{
ProjectViewModelCollection = new ObservableCollection<ProjectViewModel>() ;
ProjectViewModelCollection.Add ( new ProjectViewModel() ) ;
ProjectViewModelCollection.Add ( new ProjectViewModel() ) ;
}
}
class ProjectViewModel
{
public ObservableCollection<SelectActivityViewModel> SelectActivityViewModelCollection { get; private set; }
public string Header { get ; } = "ProjectViewModel" ;
public ProjectViewModel ( )
{
SelectActivityViewModelCollection = new ObservableCollection<SelectActivityViewModel>() ;
SelectActivityViewModelCollection.Add ( new SelectActivityViewModel() ) ;
SelectActivityViewModelCollection.Add ( new SelectActivityViewModel() ) ;
}
}
class SelectActivityViewModel
{
public ObservableCollection<ToolsViewModel> ToolsViewModelCollection { get; private set; }
public string Header { get ; } = "SelectActivityViewModel" ;
public SelectActivityViewModel ( )
{
ToolsViewModelCollection = new ObservableCollection<ToolsViewModel>() ;
ToolsViewModelCollection.Add ( new ToolsViewModel() ) ;
ToolsViewModelCollection.Add ( new ToolsViewModel() ) ;
}
}
class ToolsViewModel
{
public ObservableCollection<SheetsViewModel> SheetsViewModelCollection { get; private set; }
public ObservableCollection<FeaturesViewModel> FeaturesViewModelCollection { get; private set; }
public ObservableCollection<ViewModelBase> ViewModelCollection { get; private set; }
public string Header { get ; } = "ToolsViewModel" ;
public ToolsViewModel ( )
{
SheetsViewModelCollection = new ObservableCollection<SheetsViewModel>() ;
SheetsViewModelCollection.Add ( new SheetsViewModel() ) ;
SheetsViewModelCollection.Add ( new SheetsViewModel() ) ;
FeaturesViewModelCollection = new ObservableCollection<FeaturesViewModel>() ;
FeaturesViewModelCollection.Add ( new FeaturesViewModel() ) ;
FeaturesViewModelCollection.Add ( new FeaturesViewModel() ) ;
// Make a single collection with all children
ViewModelCollection = new ObservableCollection<ViewModelBase>() ;
foreach ( var o in SheetsViewModelCollection )
ViewModelCollection.Add ( o ) ;
foreach ( var o in FeaturesViewModelCollection )
ViewModelCollection.Add ( o ) ;
}
}
class SheetsViewModel : ViewModelBase
{
public string Header { get ; } = "SheetsViewModel" ;
}
class FeaturesViewModel : ViewModelBase
{
public ObservableCollection<UseCaseViewModel> UseCaseViewModelCollection { get; private set; }
public string Header { get ; } = "FeaturesViewModel" ;
public FeaturesViewModel ( )
{
UseCaseViewModelCollection = new ObservableCollection<UseCaseViewModel>() ;
UseCaseViewModelCollection.Add ( new UseCaseViewModel() ) ;
UseCaseViewModelCollection.Add ( new UseCaseViewModel() ) ;
}
}
class UseCaseViewModel
{
public string Header { get ; } = "UseCaseViewModel" ;
}
}
我对XAML做了一些更改:
(1)我已为以下内容定义了其他模板:
(2)我已经将HierarchicalDataTemplate定义为资源而没有任何嵌套。
这是个人喜好。我认为你使用HierarchicalDataTemplate.ItemTemplate的方法也有效。
<Window x:Class="TreeViewTest.MainWindow"
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:VM="clr-namespace:TreeViewTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<TreeView ItemsSource="{Binding ProjectViewModelCollection}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type VM:ProjectViewModel}" ItemsSource="{Binding SelectActivityViewModelCollection}">
<StackPanel Orientation="Horizontal">
<Image Source="./resources/New_Package.png" Width="15" Height="15"/>
<TextBlock Text="{Binding Header}"></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type VM:SelectActivityViewModel}" ItemsSource="{Binding ToolsViewModelCollection}">
<StackPanel Orientation="Horizontal">
<Image Source="./resources/New_Package.png" Width="15" Height="15"/>
<TextBlock Text="{Binding Header}"></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type VM:ToolsViewModel}" ItemsSource="{Binding ViewModelCollection}">
<StackPanel Orientation="Horizontal">
<Image Source="./resources/New_Package.png" Width="15" Height="15"/>
<TextBlock Text="{Binding Header}"></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type VM:FeaturesViewModel }" ItemsSource="{Binding UseCaseViewModelCollection}">
<StackPanel Orientation="Horizontal">
<Image Source="./resources/New_Package.png" Width="15" Height="15"/>
<TextBlock Text="{Binding Header}"></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type VM:SheetsViewModel}">
<StackPanel Orientation="Horizontal">
<Image Source="./resources/New_Package.png" Width="15" Height="15"/>
<TextBlock Text="{Binding Header}"></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type VM:UseCaseViewModel}">
<StackPanel Orientation="Horizontal">
<Image Source="./resources/New_Package.png" Width="15" Height="15"/>
<TextBlock Text="{Binding Header}"></TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</Window>
DataContext在代码后面初始化如下。还有其他方法可以做到这一点。
public MainWindow ( )
{
DataContext = new ViewModel() ;
InitializeComponent ();
}
我能够在五个级别上显示所有六种类型,如下所示: