由不同的List到TreeView
本文关键字:TreeView List | 更新日期: 2023-09-27 18:07:46
我想将Node类的对象绑定到一个树视图。
节点类public class Node
{
public string Text { get; set; }
public List<Node> Child { get; set; }
public List<NodeAttribute> Attributes { get; set; }
public bool IsLeafNode { get; set; }
public bool HasAttributes { get; set; }
}
NodeAttribute
public class NodeAttribute
{
public string Attribute { get; set; }
public string Value { get; set; }
}
我可以使用HierarchicalDataTemplate显示Child,但不能使用Attributes。
<TreeView Name="tv" ItemsSource="{Binding Child}">
<TreeView.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding Child}" DataType="{x:Type tvcc:Node}">
<StackPanel>
<TextBlock Text="{Binding Text}"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
我想样式的孩子和属性不同
您需要一个CompositeCollection来组合Child和Attributes,并将它们绑定到HierarchicalDataTemplate的ItemsSource
我为你准备了一个样品
在Node类中添加了CompositeCollection ChildAndAttributes
public class Node
{
public Node()
{
Child = new List<Node>();
Attributes = new List<NodeAttribute>();
}
public string Text { get; set; }
public List<Node> Child { get; set; }
public List<NodeAttribute> Attributes { get; set; }
public bool IsLeafNode { get; set; }
public bool HasAttributes { get; set; }
CompositeCollection comp;
public CompositeCollection ChildAndAttributes
{
get
{
if (comp == null)
{
comp = new CompositeCollection();
comp.Add(new CollectionContainer() { Collection = Child });
comp.Add(new CollectionContainer() { Collection = Attributes });
}
return comp;
}
}
}
如果需要,您可以调整组合集合使其首先具有属性,只需更改添加到集合
的顺序XAML
<TreeView Name="tv">
<TreeView.Resources>
<!--created seperate tempates for Node and NodeAttribute-->
<DataTemplate DataType="{x:Type tvcc:Node}">
<TextBlock Text="{Binding Text}"
Foreground="Navy" />
</DataTemplate>
<DataTemplate DataType="{x:Type tvcc:NodeAttribute}">
<TextBlock Text="{Binding Attribute}"
Foreground="Crimson" />
</DataTemplate>
</TreeView.Resources>
<!--moved your original template to Item Template or tree-->
<TreeView.ItemTemplate>
<!--binded ChildAndAttributes to ItemsSource-->
<HierarchicalDataTemplate ItemsSource="{Binding ChildAndAttributes}">
<!--this will pick up the data template for respective element-->
<ContentControl Content="{Binding}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
<!--below is sample data-->
<tvcc:Node Text="hello">
<tvcc:Node.Attributes>
<tvcc:NodeAttribute Attribute="attribute child" />
</tvcc:Node.Attributes>
<tvcc:Node.Child>
<tvcc:Node Text="hello child">
<tvcc:Node.Attributes>
<tvcc:NodeAttribute Attribute="attribute child 1" />
</tvcc:Node.Attributes>
</tvcc:Node>
</tvcc:Node.Child>
</tvcc:Node>
<tvcc:Node Text="hello2">
<tvcc:Node.Attributes>
<tvcc:NodeAttribute Attribute="attribute child 2" />
</tvcc:Node.Attributes>
<tvcc:Node.Child>
<tvcc:Node Text="hello child 2">
<tvcc:Node.Attributes>
<tvcc:NodeAttribute Attribute="attribute child 2" />
</tvcc:Node.Attributes>
</tvcc:Node>
</tvcc:Node.Child>
</tvcc:Node>
</TreeView>
您可以根据需要修改数据模板
替代方法
你也可以修改你现有的模板来达到类似的效果,而不用使用CompositCollections
<HierarchicalDataTemplate ItemsSource="{Binding Child}"
DataType="{x:Type tvcc:Node}">
<StackPanel>
<TextBlock Text="{Binding Text}"
Foreground="Navy" />
<ItemsControl ItemsSource="{Binding Attributes}" Margin="10,0,0,0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Attribute}"
Foreground="Crimson" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</HierarchicalDataTemplate>
你可以两者都试试,然后选择最适合你需要的
您将不得不使用CompositeCollection来解决您的问题。
下面是将节点转换为组合集合的转换器
public class CompositeNodeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var node = value as Node;
CompositeCollection collection = new CompositeCollection();
CollectionContainer container = new CollectionContainer();
container.Collection = node.Child;
collection.Add(container);
container = new CollectionContainer();
container.Collection = node.Attributes;
collection.Add(container);
return collection;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
然后你可以在xaml中将其绑定为:
<TreeView Name="tv" ItemsSource="{Binding NodeCollection}">
<TreeView.Resources>
<controls:CompositeNodeConverter x:Key="CompositeNodeConverter"></controls:CompositeNodeConverter>
<HierarchicalDataTemplate ItemsSource="{Binding Converter={StaticResource CompositeNodeConverter}}" DataType="{x:Type controls:Node}">
<StackPanel>
<TextBlock Text="{Binding Text}"/>
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type controls:NodeAttribute}">
<StackPanel>
<TextBlock Text="{Binding Value}"/>
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>