如何基于Type在TreeViewItem上定义不同的样式

时间:2013-12-09 09:15:09

标签: wpf xaml hierarchicaldatatemplate

我有自己的基于this post的树视图实现,但是我根据treeviewitem中的对象类型定义了不同的样式。我知道简单的方法是定义一个模板选择器,但是当你有两个HierarchicalDataTemplates时我无法弄清楚它是如何工作的。

 <HierarchicalDataTemplate DataType="{x:Type domainLayer:Folder}" ItemsSource="{Binding Converter={StaticResource BaseTypeConverter}}" />
 <HierarchicalDataTemplate DataType="{x:Type domainLayer:Document}" ItemsSource="{Binding Converter={StaticResource BaseTypeConverter}}" />

我使用这些模板来延迟加载我的树,这很好。还为所有TreeListViewItem定义了一个Style。也许还有一个解决方案,但我无法弄清楚如何定义我的TreeListViewItem是文件夹还是文档。

非常感谢任何帮助。如果您需要更多代码,请告诉我们!

更新10:40 am:

在样式中,为每个TreeListViewItem定义行:

<Style x:Key="cxc" TargetType="{x:Type local:TreeListViewItem}">
    <Setter Property="FontFamily" Value="TradeGothic LT" />
    <Setter Property="FontSize" Value="14px" />
    <Setter Property="Foreground" Value="{StaticResource TextBrush}" />
    <Setter Property="Background" Value="Transparent" />
    <EventSetter Event="MouseDoubleClick" Handler="OnItemMouseDoubleClick" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:TreeListViewItem}">
                <StackPanel>
                    <Border Name="Bd"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            Padding="{TemplateBinding Padding}">
                        <GridViewRowPresenter x:Name="PART_Header"
                                                Content="{TemplateBinding Header}"
                                                Columns="{Binding Path=Columns,RelativeSource={RelativeSource AncestorType={x:Type local:TreeListView}}}"
                                                />
                    </Border>
                    <ItemsPresenter x:Name="ItemsHost" />
                </StackPanel>
                <ControlTemplate.Triggers>
<!-- ... -->

当我将模板(StackPanel标签中的所有内容)复制到HierarchicalDataTemplate时,出现错误:无法在“ContentPresenter”类型上找到静态成员“BackgroundProperty”。

2 个答案:

答案 0 :(得分:1)

您似乎对WPF提供的不同Template有点困惑。首先,我们可以为StyleTreeViewItem),数据项'容器'定义ItemContainerStyle。然后,我们可以为容器中显示的数据项(DataTemplate)或您案例中的ItemTemplate定义HierarchicalDataTemplate

所以不要试图将您的数据项Binding放在ItemContainerStyle中,也不要将您的UI元素Binding放在DataTemplate中,你应该没问题。请注意,您可以提供一个DataTemplate / HierarchicalDataTemplate ,而无需为集合中的每种数据类型设置x:Key属性,也无需使用{{ 1}} ...让WPF根据数据项的类型隐式选择DataTemplateSelector。这是一个简单的例子:

在代码中:

DataTemplate

在XAML中:

public class BaseClass { }

public class ClassA : BaseClass { }

public class ClassB : BaseClass { }

...

public Observablecollection<BaseClass> Items { get ; set; }

<ListBox ItemsSource="{Binding Items}"> <ListBox.Resources> <DataTemplate DataType="{x:Type DataTypes:ClassA}"> <Ellipse Fill="Red" /> </DataTemplate> <DataTemplate DataType="{x:Type DataTypes:ClassB}"> <Rectangle Fill="Blue" /> </DataTemplate> </ListBox.Resources> </ListBox> 会显示ListBox项的红色圆圈和ClassA项目的蓝色矩形。你可以为你的文件夹和文件做类似的事情

答案 1 :(得分:0)

我已经解决了我的问题如下。在前面提到的Style中,我添加了一个新的MultiDataTrigger:

<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <Condition
            Binding="{Binding RelativeSource={RelativeSource Self}, Path=Header, Converter={StaticResource IsFolder}}"
            Value="False" />
        <Condition
            Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}"
            Value="True" />
    </MultiDataTrigger.Conditions>
    <Setter TargetName="Bd"
            Property="Background"
            Value="{StaticResource HighlightBackgroundBrush}" />
</MultiDataTrigger>

这似乎有效并且看起来像是正确的解决方案。谢谢Sheridan的背景。