首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >HierarchicalDataTemplate.DataType是接口,如何实现2级TreeView

HierarchicalDataTemplate.DataType是接口,如何实现2级TreeView
EN

Stack Overflow用户
提问于 2013-07-23 08:29:52
回答 2查看 4.2K关注 0票数 3

我知道如何通过将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:

代码语言:javascript
运行
复制
<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>

代码语言:javascript
运行
复制
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;
    }
}
EN

回答 2

Stack Overflow用户

发布于 2013-07-24 05:02:03

我发现了问题。

代码语言:javascript
运行
复制
public Folder : IFolder
{
    ...
    public ICollection<IFolder> SubFolders { get; set; }
    public ICollection<IFile> Files { get; set; }
}

应:

代码语言:javascript
运行
复制
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所必需的。

票数 2
EN

Stack Overflow用户

发布于 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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17805122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档