WPF - 如何显示混合自引用实体和外部实体的 TreeView

WPF - How to display TreeView with a mix of self-referencing and external entities

我正在尝试混合使用自引用实体和外部实体来呈现 TreeView,但找不到任何有效的解决方案..

我有以下型号:

# Folder
-> string Name
-> Folder ParentFolder
-> Collection<Folder> Children
-> Collection<Document> Documents

# Document
-> string Name
-> Folder Folder

我正在尝试将其显示为这样的文件系统层次结构:

+ Folder 1
  + Folder 1.1
    - Doc 1
    - Doc 2
+ Folder 2
  + Folder 2.1
  + Folder 2.2
    - Doc 3
  - Doc 4

绑定到视图的 ViewModel 包含一个 Collection<Folder> Folders

我在 XAML 中尝试了很多不同的简单绑定和 MultiBinding 组合,但都没有成功..
这是我的 current XAML(因为没有显示层次结构所以不起作用):

<TreeView ItemsSource="{Binding Folders}">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type model:Folder}">
            <HierarchicalDataTemplate.ItemsSource>
                <MultiBinding>
                    <Binding Path="Children" />
                    <Binding Path="Documents" />
                </MultiBinding>
            </HierarchicalDataTemplate.ItemsSource>

            <TextBlock Text="{Binding Name}" Background="Blue"/>
        </HierarchicalDataTemplate>

        <DataTemplate DataType="{x:Type model:Document}">
            <TextBlock Text="{Binding Name}" Background="Red"/>
        </DataTemplate>
    </TreeView.Resources>
</TreeView>

我还尝试了以下显示文件夹层次结构但不显示文档的方法(我认为这是由于未在 XAML 中的任何位置指定 Documents 属性 但不知道如何..):

<TreeView ItemsSource="{Binding Folders}">
    <TreeView.Resources>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}" DataType="{x:Type model:Folder}">
            <TextBlock Text="{Binding Name}"/>
        </HierarchicalDataTemplate>

        <DataTemplate DataType="{x:Type model:Document}">
            <TextBlock Text="{Binding Name}" Background="Red"/>
        </DataTemplate>
    </TreeView.Resources>
</TreeView>

感谢您的帮助!

如果您只是定义和使用创建文件夹和文档的复合集合的转换器,您当前的 XAML 应该可以工作:

public class Converter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        IEnumerable<object> folders = values[0] as IEnumerable<object>;
        IEnumerable<object> docs = values[1] as IEnumerable<object>;

        if (folders != null && docs != null)
            return Enumerable.Concat(folders, docs);
        else if (folders != null)
            return folders;
        else if (docs != null)
            return docs;

        return null;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) =>
        throw new NotSupportedException();
}

XAML:

<TreeView ItemsSource="{Binding Folders}">
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type model:Folder}">
            <HierarchicalDataTemplate.ItemsSource>
                <MultiBinding>
                    <MultiBinding.Converter>
                        <model:Converter />
                    </MultiBinding.Converter>
                    <Binding Path="Children" />
                    <Binding Path="Documents" />
                </MultiBinding>
            </HierarchicalDataTemplate.ItemsSource>
            <TextBlock Text="{Binding Name}" Background="Blue"/>
        </HierarchicalDataTemplate>

        <DataTemplate DataType="{x:Type model:Document}">
            <TextBlock Text="{Binding Name}" Background="Red"/>
        </DataTemplate>
    </TreeView.Resources>
</TreeView>