我想将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。
<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>
我想以不同的方式设置Child和属性的样式。
答案 0 :(得分:1)
你需要一个CompositeCollection来组合Child和Attributes并将它们绑定到HierarchicalDataTemplate的ItemsSource
我为你准备了一个样品
在Node类
中添加了CompositeCollection ChildAndAttributespublic 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>
您可以尝试两者并选择最适合您需求的产品
答案 1 :(得分:1)
您必须使用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>