我知道如何通过将TreeView定义为2个concreate类来实现两个级别的HierarchicalDataTemplate.DataType。我还找到了一些关于定义HierarchicalDataTemplate.DataType以进行接口的主题,如:WPF HiercharchicalDataTemplate.DataType: How to react on interfaces? Any way to use interfaces with wpf HierarchicalDataTemplate
但是我在TreeView中有两个级别:文件夹和文件,它由两个接口收缩: IFolder和IFile。创建嵌套TreeViewItems时,会抛出TargetInvocationException。但是,只要创建一个级别的TreeViewItem就可以了。
这是代码:(可以在这里下载整个VS2010解决方案(下载后将扩展名从png重命名为zip ):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;
}
}
发布于 2013-07-24 05:02:03
我发现了问题。
public Folder : IFolder
{
...
public ICollection<IFolder> SubFolders { get; set; }
public ICollection<IFile> Files { get; set; }
}
应:
public Folder : IFolder
{
...
private ICollection<IFolder> _subFolders = new ObservableCollection<IFolder>();
public ICollection<IFolder> SubFolders
{
get { return _subFolders; }
set { _subFolders = value; }
}
private ICollection<IFile> _files = new ObservableCollection<IFile>();
public ICollection<IFile> Files
{
get { return _files; }
set { _files = value; }
}
...
}
我只是没有给他们一个新的例子。
顺便说一句: DataTemplateSelector是接口DataType所必需的。
发布于 2013-07-23 11:21:49
我相信你可能看错了。使用HierarchicalDataTemplate
声明父层中的数据类型,最重要的是声明包含子项的属性。把它看作是设置数据结构。
然后,您可以简单地使用普通的附加DataTemplate
来对将要使用的不同数据类型进行样式设置。如果您在DataTemplate
节中声明Resources
s而没有为它们指定键,那么它们将自动影响该类型的所有对象。
我编写了一个文件同步应用程序,并将其样式设置为类似于Windows,我相信您正在尝试做类似的事情。但是,我不需要为我的文件和文件夹对象使用任何接口。它们都有一个Type
属性,我可以使用我编写的显示各种类型文件图标的FileTypeConverter
将其绑定到Image.Source
属性。
我设计了一个DataTemplate
用于呈现文件,另一个用于文件夹,另一个HierarchicalDataTemplate
用于使用HierarchicalDataTemplate.ItemContainerStyle
属性为每个项定义结构和容器。不幸的是,我目前无法访问该项目,因此我不能给您提供更多的代码示例。
另外,以下是一些相关的文章:
Set TreeView HierarchicalDataTemplate with 2 levels in WPF
WPF TreeView HierarchicalDataTemplate - binding to object with multiple child collections
https://stackoverflow.com/questions/17805122
复制相似问题