如何将其他项模板添加到扩展WPF树视图中

时间:2011-09-27 21:22:23

标签: wpf treeview

我正在尝试设置一个可以用作公共模板的Treeview后代类 我的应用程序中的所有Treeview实例,但每个实例都有其他格式和模板。

对于基础,我有一个UserControl,它来自Treeview,具有常见样式和单个标准数据模板

<TreeView x:Class="BaseTreeView" ... >
    <TreeView.ItemContainerStyle> ... </TreeView.ItemContainerStyle>
    <TreeView.Resources>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}"  DataType="{x:Type local:BaseTreeViewItem}">
            <TextBlock Text="{Binding Caption}" />
        </HierarchicalDataTemplate>
    </TreeView.Resources>
</TreeView>

然后在每个窗口中,我使用这个扩展的Treeview并为我正在显示的特定TreeviewItem添加其他数据模板。

e.g。

<Window x:Class="Window1" ... >
    ...
    <BaseTreeView ItemsSource="{Binding RootTreeItems}" >
        <MyTreeView.Resources>
            <HierarchicalDataTemplate ItemsSource="{Binding Children}"  DataType="{x:Type ExtendedTreeViewItem1}">
                <StackPanel Orientation="Horizontal">
                    <Image Source="Images/Image1.png" />
                    <TextBlock Text="{Binding Caption}" />
                </StackPanel>
            </HierarchicalDataTemplate>
            <DataTemplate DataType="{x:Type ExtendedTreeViewItem2}">
                <StackPanel Orientation="Horizontal">
                    <Image Source="Images/Image2.png" />
                    <TextBlock Text="{Binding Caption}" />
                </StackPanel>
            </DataTemplate>
        </MyTreeView.Resources>
    </BaseTreeView>
    ...
</Window>

这编译很好,但在运行时我收到错误

  

“'设置属性'System.Windows.ResourceDictionary.DeferrableContent'引发了异常。”行号“27”和行位置“59”。“

     

“无法重新初始化ResourceDictionary实例。”

有没有解决方法,或者有人建议更好的方法来设置基本树视图模板和多个后代版本。

1 个答案:

答案 0 :(得分:0)

您可以尝试将模板移至<Window.Resources>而不是<MyTreeView.Resources>

如果它不起作用,可能使用DataTemplateSelector最适合您的情况。您可以像这样创建一个DataTemplateSelector类:

public class ExtendedTreeViewTemplateSelector : DataTemplateSelector
{
    public DataTemplate ExtendedTreeViewItem1Template { get; set; }
    public DataTemplate ExtendedTreeViewItem2Template { get; set; }


    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item is ExtendedTreeViewItem1)
            return ExtendedTreeViewItem1Template;
        if (item is ExtendedTreeViewItem2)
            return ExtendedTreeViewItem2Template;
    }
}

然后在你的XAML中使用它:

<Window x:Class="Window1" ... >
    <Window.Resources>
        <HierarchicalDataTemplate x:Key="extendedTreeViewItem1Template" ItemsSource="{Binding Children}"  DataType="{x:Type ExtendedTreeViewItem1}">
            <StackPanel Orientation="Horizontal">
                <Image Source="Images/Image1.png" />
                <TextBlock Text="{Binding Caption}" />
            </StackPanel>
        </HierarchicalDataTemplate>
        <DataTemplate x:Key="extendedTreeViewItem2Template" DataType="{x:Type ExtendedTreeViewItem2}">
            <StackPanel Orientation="Horizontal">
                <Image Source="Images/Image2.png" />
                <TextBlock Text="{Binding Caption}" />
            </StackPanel>
        </DataTemplate>
        <selector:ExtendedTreeViewTemplateSelector x:Key="treeViewTemplateSelector"
                                                   ExtendedTreeViewItem1Template="{StaticResource extendedTreeViewItem1Template}"
                                                   ExtendedTreeViewItem2Template="{StaticResource extendedTreeViewItem2Template}" />
    </Window.Resources>
    ...
    <BaseTreeView ItemsSource="{Binding RootTreeItems}"
                  ItemTemplateSelector={StaticResource treeViewTemplateSelector}" />
    ...
</Window>