'ItemTemplate' 和 'ItemTemplateSelector' 都已设置; 'ItemTemplateSelector' 将被忽略
Both 'ItemTemplate' and 'ItemTemplateSelector' are set; 'ItemTemplateSelector' will be ignored
在 之后,我还有一个关于 TreeView
的问题。
我已经拥有的是 TreeView
with HierarchicalDataTemplate
,我可以在其中更改 level2 的 HierarchicalDataTemplate
(如问题和答案中所述)。
我现在想要的是改变 Treeview
扩展器的外观。为此,我定义了一个名为 ctForTreeViewItem
的 ControlTemplate
,我这样使用它:
<Window.Resources>
<ControlTemplate x:Key="ctForTreeViewItem"
TargetType="{x:Type TreeViewItem}">
<Expander IsExpanded="True"
Background="Grey"
BorderBrush="Transparent"
Foreground="White"
BorderThickness="1,1,1,3">
<Expander.Header>
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
Padding="{TemplateBinding Control.Padding}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
Name="Bd"
SnapsToDevicePixels="True"
Grid.Column="1">
<ContentPresenter Content="{TemplateBinding HeaderedContentControl.Header}"
ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}"
ContentStringFormat="{TemplateBinding HeaderedItemsControl.HeaderStringFormat}"
ContentSource="Header"
Name="PART_Header"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>
</Expander.Header>
<Expander.Content>
<ItemsPresenter x:Name="ItemsHost" />
</Expander.Content>
</Expander>
</ControlTemplate>
<DataTemplate x:Key="Level3Template">
<Border Background="LightBlue">
<TextBlock Text="Level3"/>
</Border>
</DataTemplate>
<HierarchicalDataTemplate x:Key="Level2RedTemplate"
ItemsSource="{Binding Value}"
ItemTemplate="{StaticResource Level3Template}">
<Border Background="Red">
<TextBlock Text="Level2"/>
</Border>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="Level2YellowTemplate"
ItemsSource="{Binding Value}"
ItemTemplate="{StaticResource Level3Template}">
<Border Background="Yellow">
<TextBlock Text="Level2"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="Level1Template"
ItemsSource="{Binding Value}"
ItemTemplateSelector="{StaticResource MySelector}">
<HierarchicalDataTemplate.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="Template"
Value="{StaticResource ctForTreeViewItem}" />
</Style>
</HierarchicalDataTemplate.ItemContainerStyle>
<Border Background="Green">
<TextBlock Text="Level1"/>
</Border>
</HierarchicalDataTemplate>
</Window.Resources>
<TreeView Grid.Row="1"
Name="tv"
ItemsSource="{Binding Items}"
ItemTemplate="{StaticResource Level1Template}">
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="Template"
Value="{StaticResource ctForTreeViewItem}" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
这按预期适用于 Level1,因此在 Level 1 上,我有 TreeViewItems
以及定义的 ControlTemplate
和正确的 HierarchicalDataTemplate
。
然而,它在 Level2 上不起作用,我有一个 ItemTemplateSelector
。在这个位置,我得到这个错误:System.Windows.Data Error: 25 : Both 'ItemTemplate' and 'ItemTemplateSelector' are set; 'ItemTemplateSelector' will be ignored.
有什么方法可以将 ControlTemplate
分配给 TreeViewItem
,同时保留 ItemTemplateSelector
?甚至
有没有其他方法可以更改 TreeView
的扩展器样式?
您的 TreeViewItem ControlTemplate 已损坏。它忽略了数据模板选择器,因为你 explicitly override that by setting ContentTemplate
on the ContentPresenter
。这也类似于导致调试输出流中的(无害)错误的原因:2 级模板从其祖先那里继承 ItemTemplateSelector
,就像您在 ItemContainerStyle
上设置一次一样=16=],它将被树视图的所有 children 继承,除非某些干预 child 明确覆盖它。无需设置多次。因为 2 级模板继承 ItemTemplateSelector
并用不同的 属性 覆盖它,所以会出现错误,但这是无害的。
我通过更改 Header 的 ContentPresenter 以匹配默认的 TreeViewItem 控件模板来修复控件模板:我删除了 Content
、ContentTemplate
和 ContentStringFormat
属性。 ContentPresenter
对所有这些东西都有默认行为,所以你不需要明确指定它。
<ContentPresenter
ContentSource="Header"
Name="PART_Header"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
/>
template/template 选择器错误是无害的,但我能够通过在 2 级分层数据模板上将 ItemTemplateSelector
明确设置为 null 来消除它们:
<HierarchicalDataTemplate
x:Key="Level2RedTemplate"
ItemsSource="{Binding Value}"
ItemTemplateSelector="{x:Null}"
ItemTemplate="{StaticResource Level3Template}"
>
<Border Background="Red">
<TextBlock Text="Level2"/>
</Border>
</HierarchicalDataTemplate>
在 TreeView
的问题。
我已经拥有的是 TreeView
with HierarchicalDataTemplate
,我可以在其中更改 level2 的 HierarchicalDataTemplate
(如问题和答案中所述)。
我现在想要的是改变 Treeview
扩展器的外观。为此,我定义了一个名为 ctForTreeViewItem
的 ControlTemplate
,我这样使用它:
<Window.Resources>
<ControlTemplate x:Key="ctForTreeViewItem"
TargetType="{x:Type TreeViewItem}">
<Expander IsExpanded="True"
Background="Grey"
BorderBrush="Transparent"
Foreground="White"
BorderThickness="1,1,1,3">
<Expander.Header>
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
Padding="{TemplateBinding Control.Padding}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
Name="Bd"
SnapsToDevicePixels="True"
Grid.Column="1">
<ContentPresenter Content="{TemplateBinding HeaderedContentControl.Header}"
ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}"
ContentStringFormat="{TemplateBinding HeaderedItemsControl.HeaderStringFormat}"
ContentSource="Header"
Name="PART_Header"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>
</Expander.Header>
<Expander.Content>
<ItemsPresenter x:Name="ItemsHost" />
</Expander.Content>
</Expander>
</ControlTemplate>
<DataTemplate x:Key="Level3Template">
<Border Background="LightBlue">
<TextBlock Text="Level3"/>
</Border>
</DataTemplate>
<HierarchicalDataTemplate x:Key="Level2RedTemplate"
ItemsSource="{Binding Value}"
ItemTemplate="{StaticResource Level3Template}">
<Border Background="Red">
<TextBlock Text="Level2"/>
</Border>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="Level2YellowTemplate"
ItemsSource="{Binding Value}"
ItemTemplate="{StaticResource Level3Template}">
<Border Background="Yellow">
<TextBlock Text="Level2"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="Level1Template"
ItemsSource="{Binding Value}"
ItemTemplateSelector="{StaticResource MySelector}">
<HierarchicalDataTemplate.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="Template"
Value="{StaticResource ctForTreeViewItem}" />
</Style>
</HierarchicalDataTemplate.ItemContainerStyle>
<Border Background="Green">
<TextBlock Text="Level1"/>
</Border>
</HierarchicalDataTemplate>
</Window.Resources>
<TreeView Grid.Row="1"
Name="tv"
ItemsSource="{Binding Items}"
ItemTemplate="{StaticResource Level1Template}">
<TreeView.ItemContainerStyle>
<Style TargetType="TreeViewItem">
<Setter Property="Template"
Value="{StaticResource ctForTreeViewItem}" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
这按预期适用于 Level1,因此在 Level 1 上,我有 TreeViewItems
以及定义的 ControlTemplate
和正确的 HierarchicalDataTemplate
。
然而,它在 Level2 上不起作用,我有一个 ItemTemplateSelector
。在这个位置,我得到这个错误:System.Windows.Data Error: 25 : Both 'ItemTemplate' and 'ItemTemplateSelector' are set; 'ItemTemplateSelector' will be ignored.
有什么方法可以将
ControlTemplate
分配给TreeViewItem
,同时保留ItemTemplateSelector
?甚至有没有其他方法可以更改
TreeView
的扩展器样式?
您的 TreeViewItem ControlTemplate 已损坏。它忽略了数据模板选择器,因为你 explicitly override that by setting ContentTemplate
on the ContentPresenter
。这也类似于导致调试输出流中的(无害)错误的原因:2 级模板从其祖先那里继承 ItemTemplateSelector
,就像您在 ItemContainerStyle
上设置一次一样=16=],它将被树视图的所有 children 继承,除非某些干预 child 明确覆盖它。无需设置多次。因为 2 级模板继承 ItemTemplateSelector
并用不同的 属性 覆盖它,所以会出现错误,但这是无害的。
我通过更改 Header 的 ContentPresenter 以匹配默认的 TreeViewItem 控件模板来修复控件模板:我删除了 Content
、ContentTemplate
和 ContentStringFormat
属性。 ContentPresenter
对所有这些东西都有默认行为,所以你不需要明确指定它。
<ContentPresenter
ContentSource="Header"
Name="PART_Header"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
/>
template/template 选择器错误是无害的,但我能够通过在 2 级分层数据模板上将 ItemTemplateSelector
明确设置为 null 来消除它们:
<HierarchicalDataTemplate
x:Key="Level2RedTemplate"
ItemsSource="{Binding Value}"
ItemTemplateSelector="{x:Null}"
ItemTemplate="{StaticResource Level3Template}"
>
<Border Background="Red">
<TextBlock Text="Level2"/>
</Border>
</HierarchicalDataTemplate>