我需要将自定义树视图构建为用户控件。我为了示例TreeViewEx而调用它:
<UserControl x:Class="WpfApplication4.TreeViewEx"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="root">
<Grid>
<TreeView ItemsSource="{Binding Path=ItemsSource, ElementName=root}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Node : "/>
<ContentControl Content="{Binding Path=AdditionalContent, ElementName=root}"/>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</UserControl>
我们的想法是拥有ItemTemplate内容的固定部分及其可自定义的部分。
当然,我在TreeViewEx类上创建了两个依赖项属性:
public partial class TreeViewEx
{
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
"ItemsSource", typeof(IEnumerable), typeof(TreeViewEx));
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public static readonly DependencyProperty AdditionalContentProperty = DependencyProperty.Register(
"AdditionalContent", typeof(object), typeof(TreeViewEx));
public object AdditionalContent
{
get { return GetValue(AdditionalContentProperty); }
set { SetValue(AdditionalContentProperty, value); }
}
public TreeViewEx()
{
InitializeComponent();
}
}
有一个像这样的简单节点类:
public class Node
{
public string Name { get; set; }
public int Size { get; set; }
public IEnumerable<Node> Children { get; set; }
}
我会提供树视图。我在一个WPF测试项目的MainWindow上放置了一个TreeViewEx实例:
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:local="clr-namespace:WpfApplication4">
<Grid>
<local:TreeViewEx x:Name="tree">
<local:TreeViewEx.AdditionalContent>
<TextBlock Text="{Binding Name}"/>
</local:TreeViewEx.AdditionalContent>
</local:TreeViewEx>
</Grid>
</Window>
最后喂它:
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
var dummyData = new ObservableCollection<Node>
{
new Node
{
Name = "Root",
Size = 3,
Children = new ObservableCollection<Node>
{
new Node{
Name="Child1",
Size=2,
Children = new ObservableCollection<Node>{
new Node{
Name = "Subchild",
Size = 1
}
}
}
}
}
};
tree.ItemsSource = dummyData;
}
}
然而它没有按预期工作,即一开始ContentControl有数据但是当我展开节点时它不显示ContentControl的内容。
我真的不明白..我应该使用 DataTemplate 或其他什么?
答案 0 :(得分:2)
问题是您将内容设置为控件的实例,并且该控件只能有一个父级。展开树并将其添加到第二个节点时,它会将其从第一个节点中删除。
如您所料,您希望向TreeViewEx而不是控件提供DataTemplate。您可以使用ContentPresenter在树的每个级别实例化模板:
将AdditionalContentProperty替换为:
public static readonly DependencyProperty AdditionalContentTemplateProperty = DependencyProperty.Register(
"AdditionalContentTemplate", typeof(DataTemplate), typeof(TreeViewEx));
public DataTemplate AdditionalContentTemplate
{
get { return (DataTemplate)GetValue(AdditionalContentTemplateProperty); }
set { SetValue(AdditionalContentTemplateProperty, value); }
}
将UserControl的XAML中的HierarchicalDataTemplate更改为:
<StackPanel Orientation="Horizontal">
<TextBlock Text="Node : "/>
<ContentPresenter ContentTemplate="{Binding Path=AdditionalContentTemplate, ElementName=root}"/>
</StackPanel>
并将MainWindow更改为:
<local:TreeViewEx x:Name="tree">
<local:TreeViewEx.AdditionalContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</local:TreeViewEx.AdditionalContentTemplate>
</local:TreeViewEx>