我知道如何通过将 HierarchicalDataTemplate.DataType 定义为 2 个 concreate 类来实现 2 个级别的 TreeView。我还发现了一些关于将 HierarchicalDataTemplate.DataType 定义为接口的主题,例如: WPF HiercharchicalDataTemplate.DataType: How to react on interfaces? 使用 wpf HierarchicalDataTemplate 接口的任何方式
但是我在TreeView中有两个层次:文件夹和文件,它由两个接口收缩:IFolder和IFile。当我创建嵌套的 TreeViewItems 时,会引发 TargetInvocationException。但是如果只创建一层 TreeViewItem 就可以了。
这是代码:(可以在这里下载整个VS2010解决方案(下载后将扩展名从png重命名为zip):http: //img.bbs.csdn.net/upload/201307/23/1374565982_74852.png )
MainWindow.xaml:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:ItemTemplateSelector x:Key="ItemTemplateSelector">
<local:ItemTemplateSelector.FolderTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:IFolder}" ItemsSource="{Binding Items}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</local:ItemTemplateSelector.FolderTemplate>
<local:ItemTemplateSelector.FileTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:IFile}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</local:ItemTemplateSelector.FileTemplate>
</local:ItemTemplateSelector>
</Window.Resources>
<Grid>
<TreeView Name="tvwFiles" ItemTemplateSelector="{DynamicResource ItemTemplateSelector}" />
</Grid>
class ItemTemplateSelector : DataTemplateSelector
{
public DataTemplate FolderTemplate { get; set; }
public DataTemplate FileTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
IFolder folder = item as IFolder;
if (folder != null)
{
return FolderTemplate;
}
IFile file = item as IFile;
if (file != null)
{
return FileTemplate;
}
return null;
}
}
public interface IFolder
{
string Name { get; set; }
}
public interface IFile
{
string Name { get; set; }
}
public class Folder : IFolder
{
public string Name { get; set; }
public ICollection<object> Items
{
get
{
ICollection<object> items = new List<object>();
if (SubFolders != null)
{
foreach (var folder in SubFolders)
items.Add(folder);
}
if (Files != null)
{
foreach (var file in Files)
items.Add(file);
}
return items;
}
}
public ICollection<IFolder> SubFolders { get; set; }
public ICollection<IFile> Files { get; set; }
public Folder(string name)
{
Name = name;
}
}
public class File : IFile
{
public string Name { get; set; }
public File(string name)
{
Name = name;
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ObservableCollection<object> dirs = new ObservableCollection<object>();
Folder folder = new Folder("Root");
dirs.Add(folder);
for (int i = 0; i < 3; ++i)
{
Folder subfolder = new Folder("Folder" + i);
for (int j = 0; j < 3; ++j)
{
File File = new File("File" + j);
subfolder.Files.Add(File);
}
folder.SubFolders.Add(subfolder);
}
tvwFiles.ItemsSource = dirs;
}
}