使用 HierarchialdataTemplate 的多级 WPF Treeview
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16674967/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Treeview with multiple levels using HierarchialdataTemplate
提问by isakavis
Here is my code for creating a Treeview that has multiple levels with checkbox to be shown. I am not able to show the Files under the folders with the following code. What is wrong with my Xaml that causes this? Or it cannot be done?
这是我用于创建具有多个级别并显示复选框的 Treeview 的代码。我无法使用以下代码显示文件夹下的文件。我的 Xaml 有什么问题导致了这个?还是做不到?
Window1.xaml
窗口1.xaml
<Window x:Class="TreeViewSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TreeViewSample"
Title="Window1" Height="500" Width="800">
<DockPanel>
<TreeView DockPanel.Dock="Left" Width="300" ItemsSource="{Binding Folders}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:Folder}" ItemsSource="{Binding Folders}">
<StackPanel Orientation="Horizontal">
<CheckBox Margin="2" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:File}" ItemsSource="{Binding Files}">
<StackPanel Orientation="Horizontal">
<CheckBox Margin="2" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
<Grid></Grid>
</DockPanel>
Window1.xaml.cs codebehind constructor
Window1.xaml.cs 代码隐藏构造函数
this.DataContext = new Window1ViewModel();
Window1ViewModel
Window1ViewModel
public class Window1ViewModel : INotifyPropertyChanged
{
public Window1ViewModel()
{
_folders = new ObservableCollection<Folder>(Sample.GetFoldersAndFiles());
}
private ObservableCollection<Folder> _folders;
public ObservableCollection<Folder> Folders
{
get { return _folders; }
set { _folders = value; OnPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName]string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Sample Data and Classes
示例数据和类
public class Sample
{
public static List<Folder> GetFoldersAndFiles()
{
var folders = new List<Folder>();
Folder folder1 = new Folder { Name ="Folder 1" };
Folder folder2 = new Folder { Name = "Folder 2" };
Folder folder3 = new Folder { Name = "Folder 3" };
Folder folder11 = new Folder { Name = "Folder 11" };
Folder folder12 = new Folder { Name = "Folder 12" };
Folder folder22 = new Folder { Name = "Folder 22" };
folder1.Folders.Add(folder11);
folder1.Folders.Add(folder12);
folder2.Folders.Add(folder22);
File file1 = new File { Name="File 1" };
File file2 = new File { Name = "File 2" };
File file3 = new File { Name = "File 3" };
File file4 = new File { Name = "File 4" };
File file11 = new File { Name = "File 11" };
File file31 = new File { Name = "File 31" };
file1.Files.Add(file11);
file3.Files.Add(file31);
folder1.Files.Add(file1);
folder1.Files.Add(file2);
folder2.Files.Add(file3);
folder3.Files.Add(file4);
folders.Add(folder1);
folders.Add(folder2);
folders.Add(folder3);
return folders;
}
}
public class Folder
{
public Folder()
{
Folders = new List<Folder>();
Files = new List<File>();
}
public string Name { get; set; }
public ICollection<Folder> Folders { get; set; }
public ICollection<File> Files { get; set; }
}
public class File
{
public File()
{
Files = new List<File>();
}
public string Name { get; set; }
public Folder Folder { get; set; }
public ICollection<File> Files { get; set; } // This groups files together under a single file.
}
I am expecting to have the tree as below:
我期待有如下树:
Folder1
- Folder11
- Folder12
- File1
- File2
Folder2
- Folder22
- File3 etc.,
文件夹 1
- 文件夹11
- 文件夹12
- 文件 1
- 文件2
文件夹2
- 文件夹22
- 文件3等,
回答by kmatyaszek
You can use CompositeCollection(msdn).
您可以使用CompositeCollection(msdn)。
First you should add to Folderclass property which will return CompositeCollection.
首先,您应该添加到Folder将返回的类属性CompositeCollection。
public class Folder
{
public Folder()
{
Folders = new List<Folder>();
Files = new List<File>();
}
public string Name { get; set; }
public ICollection<Folder> Folders { get; set; }
public ICollection<File> Files { get; set; }
public IEnumerable Items
{
get
{
var items = new CompositeCollection();
items.Add(new CollectionContainer { Collection = Folders });
items.Add(new CollectionContainer { Collection = Files });
return items;
}
}
}
After first step you should modify HierarchicalDataTemplateas following:
第一步后,您应该修改HierarchicalDataTemplate如下:
<HierarchicalDataTemplate DataType="{x:Type local:Folder}" ItemsSource="{Binding Items}">
<StackPanel Orientation="Horizontal">
<CheckBox Margin="2" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:File}">
<StackPanel Orientation="Horizontal">
<CheckBox Margin="2" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
回答by isakavis
Got it working. The following is the change I did.
得到它的工作。以下是我所做的更改。
public IList Children
{
get
{
return new CompositeCollection()
{
new CollectionContainer() { Collection = Folders },
new CollectionContainer() { Collection = Files }
};
}
}
<HierarchicalDataTemplate DataType="{x:Type local:Folder}" ItemsSource="{Binding Children}">
Here is the link that gave me the solution:
这是给我解决方案的链接:

