gpt4 book ai didi

c# - WPF Treeview 和数据绑定(bind)目录树

转载 作者:行者123 更新时间:2023-12-03 10:22:28 26 4
gpt4 key购买 nike

我正在尝试实现一个目录 TreeView ,它还显示了我的 MVVM 项目中的所有文件。 Model 中的我的文件夹和文件结构是这样的:

public class UserDirectory
{
private ObservableCollection<UserFile> files;
private ObservableCollection<UserDirectory> subfolders;
private String directoryPath;
//public getters and setters...
}

public class UserFile
{
private String filePath;
private Category category; //Archive, Document, Exe, etc...
//public getters and setters
}

我想在 TreeView 中显示它们,但在阅读 this very helpful Josh Smith article 之后,以及其他各种来源,我仍然不知道如何使用 HierarchicalDataTemplate .

可能的解决方案

我发现也许我必须创建一个特定的类型,比如 Item ,仅用于显示文件和目录的名称,
public class Item
{
private List<String> directories;
private List<String> files;
}

但我想重用我的类结构,因为我需要显示 Category UserFile 的数据, 例如。

问题

如何在维护当前数据结构时显示文件和子文件夹?

This is an example of what I want to reach (对不起,图片上传不起作用)

最佳答案

XAML

<TreeView
ItemsSource="{Binding RootDirectoryItems}"
>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:UserDirectory}" ItemsSource="{Binding Items}">
<Label Content="{Binding Name}" />
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:UserFile}">
<Label Content="{Binding Name}" />
</DataTemplate>
</TreeView.Resources>
</TreeView>
RootDirectoryItems被假定为 View 模型的属性,如下所示:
public ObservableCollection<Object> RootDirectoryItems { get; } 
= new ObservableCollection<object>();

在 C# 中,假设存在 INotifyPropertyChanged所有属性 setter 的样板。我在 UserDirectory 中添加了两个属性:
  • Name , 一个只读属性,它只返回 DirectoryPath 的名称段.如果 DirectoryPath可能在运行时改变,它的 setter 应该调用 OnPropertyChanged("Name"); ,以便绑定(bind)查看 Name属性(property)将知道他们需要获得新值(value)。 UserFile获得了类似的Name属性(property),它与提高 PropertyChanged 的建议相同如果有可能的话。
  • Items : 再次,一个只读属性,你应该提出 PropertyChanged如果任何一个组成集合发生变化(处理 ICollectionChanged.CollectionChanged ,并且如果您有 setter ,则在 setter 中同样执行)。绑定(bind)不关心属性的声明类型,所以它只返回 System.Collections.IEnumerable -- 它甚至可以返回 object ,并且 XAML 不会在意。但是,让我们足够具体,不要过于具体以鼓励 C# 中的任何人尝试将该属性用于任何事情。

  • 如果是我,我几乎肯定会制作 UserDirectoryUserFile没有 INotifyPropertyChanged 的裸不可变“POCO”类, 如果磁盘上有任何更改,只需重新填充。我可能会通过给出 UserDirectory 来偏离不变性一个 FileWatcher并让它重新填充自己,如果我有一些理由期望目录会发生很大变化。

    所以这里是C#:
    public class UserDirectory
    {
    public ObservableCollection<UserFile> Files { get; set; } = new ObservableCollection<UserFile>();
    public ObservableCollection<UserDirectory> Subfolders { get; set; } = new ObservableCollection<UserDirectory>();

    // Concat demands a non-null argument
    public IEnumerable Items { get { return Subfolders?.Cast<Object>().Concat(Files); } }

    public String DirectoryPath { get; set; }
    public String Name { get { return System.IO.Path.GetFileName(DirectoryPath); } }
    }

    public class UserFile
    {
    public String FilePath { get; set; }
    public Category Category { get; set; }

    public String Name { get { return System.IO.Path.GetFileName(FilePath); } }
    }

    您的 Item不需要类,因为 XAML 通过“鸭子类型”工作。

    这是一个更简单的变体,也可以使用,因为 UserDirectoryUserFile有一个 Name属性(property)和 UserFile失踪了 Items属性(property)被悄悄地耸了耸肩。
        <TreeView
    ItemsSource="{Binding RootDirectoryItems}"
    >
    <TreeView.ItemTemplate>
    <HierarchicalDataTemplate ItemsSource="{Binding Items}">
    <Label Content="{Binding Name}" />
    </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
    </TreeView>

    关于c# - WPF Treeview 和数据绑定(bind)目录树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46651448/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com