我正在尝试使用数据模板将集合绑定到wpf TreeView
控件。集合中的每个项目(人物)还包含两个不同的集合(汽车,书籍)类型的汽车和书籍。
以下是节省空间所涉及的对象的简化列表。
public class Person
{
public string Name
public List<Book> Books;
public List<Car> Cars;
}
public class Book
{
public string Title
public string Author
}
public class Car
{
public string Manufacturer;
public string Model;
}
以下是我的约束方式
public MainWindow()
{
InitializeComponent();
this.treeView1.ItemsSource = this.PersonList();
}
public List<Person> PersonList()
{
List<Person> list = new List<Person>();
Book eco = new Book { Title = "Economics 101", Author = "Adam Smith"};
Book design = new Book { Title = "Web Design", Author = "Robins" };
Car corola = new Car { Manufacturer = "Toyota", Model = "2005 Corola"};
Car ford = new Car { Manufacturer = "Ford", Model = "2008 Focus"};
Person john = new Person { Name = "John", Books = new ObservableCollection<Book> { eco, design }, Cars = new ObservableCollection<Car> { corola } };
Person smith = new Person { Name = "Smith", Books = new ObservableCollection<Book> { eco, design }, Cars = new ObservableCollection<Car> { ford } };
list.AddRange(new[] {john, smith });
return list;
}
这是Xaml代码
<Grid>
<TreeView Name="treeView1">
</TreeView>
</Grid>
我希望看到树形显示看起来像这样。
>John
>Books
Economics 101 : Adam Smith
Web Design : Robins
>Cars
Totota : 2005 Corola
>Smith
>Books
Economics 101 : Adam Smith
Web Design : Robins
>Cars
Ford: 2008 Focus
此符号>
用于显示树文件夹,不应在模板中考虑。
答案 0 :(得分:7)
由于您的树有两个不同的子集合,因此有点复杂。 WPF不支持具有多个ItemsSource
定义的方案。因此,您需要将这些集合合并到CompositeCollection中。复合元素(即Car,Book)的类型匹配将自动完成。
在XAML中,您需要定义与您的类型定义匹配的所谓HierarchicalDataTemplates。如果local
指向定义Book
,Car
和Person
的名称空间,则简化的HierarchicalDataTemplates
可能如下所示:
<HierarchicalDataTemplate DataType="{x:Type local:Person}"
ItemsSource="{Binding CompositeChildren}">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Book}">
<TextBlock Text="{Binding Path=Title}" />
<!-- ... -->
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Car}">
<TextBlock Text="{Binding Path=Model}" />
<!-- ... -->
</HierarchicalDataTemplate>
然后,您需要将您的集合连接到树控件。有几种可能性,最简单的方法是在Window
类中定义属性并定义绑定:
<TreeView Items={Binding ElementName=myWindow, Path=Persons}/>
这应该指向正确的方向,但不要将我的代码作为编译就绪: - )
答案 1 :(得分:3)
CompositeCollection
是一个很好的答案,除非您无法将子集合绑定到DataContext
,因为它不是Freezable
。您只能将它们绑定到资源。 (有关详细信息,请参阅this question。)这使得它很难在HierarchicalDataTemplate
中使用,因为一个ItemsSource
中的public IEnumerable<object> Items
{
get { return Books.Concat(Cars); }
}
需要绑定到当前上下文中的属性是有用的。
如果您不需要对集合进行更改通知,则可以在视图模型中轻松实现属性,例如:
{{1}}
如果你需要对收藏品进行更改通知,那就不那么容易了。
答案 2 :(得分:1)
您需要DataTemplate
,否则WPF不知道如何显示您的对象。