WPF TreeView:使用ItemTemplateSelector和ItemContainerStyle不能同时工作

时间:2017-02-20 10:39:19

标签: wpf treeview datatemplate controltemplate

我有一个WPF TreeView我为其指定了两个HierarchicalDataTemplates,我使用模板选择器根据数据绑定对象中的类型选择应用哪一个。应用分层数据模板,我在TreeView

中看到了预期的项目名称

但是,当我尝试为树视图项设置ItemContainerStyle时,看起来不再应用分层数据模板:每个树视图项的标签都设置为对象的类名。该项目必然会被绑定。我正在应用的样式将模板设置为TreeViewItem ControlTemplate(我计划稍微修改此模板,但现在我使用的是从Visual Studio导出的未经修改的模板)。

数据模板选择器

public class NodeTypeTemplateSelector : DataTemplateSelector
{
    public DataTemplate Type1Template { get; set; }

    public DataTemplate Type2Template { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item == null) return base.SelectTemplate(null, container);

        var layer = item as LayersItemVM;
        if (layer != null)
        {
            switch (layer.NodeType)
            {
                case NodeType.Type1:
                    return Type1Template;
                case NodeType.Type2:
                    return Type2Template;
                default:
                    return base.SelectTemplate(item, container);
            }
        }
        return base.SelectTemplate(item, container);
    }
}

主窗口XAML

<Window x:Class="TreeViewSimple2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:TreeViewSimple2"
    mc:Ignorable="d"
    Loaded="MainWindow_OnLoaded"
    Title="MainWindow" Height="350" Width="525">

<Window.Resources>
  <HierarchicalDataTemplate x:Key="Type1Template">
    <StackPanel>
      <Label Content="{Binding Path=Name}"></Label>
    </StackPanel>
  </HierarchicalDataTemplate>

  <HierarchicalDataTemplate x:Key="Type2Template">
    <StackPanel>
      <Label Content="{Binding Path=Name}"></Label>
    </StackPanel>
  </HierarchicalDataTemplate>

  <local:NodeTypeTemplateSelector Type1Template="{StaticResource Type1Template}" Type2Template="{StaticResource Type2Template}" x:Key="NodeTypeTemplateSelector" />
</Window.Resources>

<Grid>
    <TreeView x:Name="TreeView" ItemTemplateSelector="{StaticResource NodeTypeTemplateSelector}">
      <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType="{x:Type TreeViewItem}">
                <Grid>
                  <Grid.ColumnDefinitions>
                    <ColumnDefinition MinWidth="19" Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="*"/>
                  </Grid.ColumnDefinitions>
                  <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition/>
                  </Grid.RowDefinitions>
                  <ToggleButton x:Name="Expander" ClickMode="Press" IsChecked="{Binding IsExpanded, RelativeSource={RelativeSource TemplatedParent}}">
                    <ToggleButton.Style>
                      <Style TargetType="{x:Type ToggleButton}">
                        <Setter Property="Focusable" Value="False"/>
                        <Setter Property="Width" Value="16"/>
                        <Setter Property="Height" Value="16"/>
                        <Setter Property="Template">
                          <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ToggleButton}">
                              <Border Background="Transparent" Height="16" Padding="5" Width="16">
                                <Path x:Name="ExpandPath" Data="M0,0 L0,6 L6,0 z" Fill="Transparent" Stroke="#FF989898">
                                  <Path.RenderTransform>
                                    <RotateTransform Angle="135" CenterY="3" CenterX="3"/>
                                  </Path.RenderTransform>
                                </Path>
                              </Border>
                              <ControlTemplate.Triggers>
                                <Trigger Property="IsChecked" Value="True">
                                  <Setter Property="RenderTransform" TargetName="ExpandPath">
                                    <Setter.Value>
                                      <RotateTransform Angle="180" CenterY="3" CenterX="3"/>
                                    </Setter.Value>
                                  </Setter>
                                  <Setter Property="Fill" TargetName="ExpandPath" Value="#FF595959"/>
                                  <Setter Property="Stroke" TargetName="ExpandPath" Value="#FF262626"/>
                                </Trigger>
                                <Trigger Property="IsMouseOver" Value="True">
                                  <Setter Property="Stroke" TargetName="ExpandPath" Value="#FF1BBBFA"/>
                                  <Setter Property="Fill" TargetName="ExpandPath" Value="Transparent"/>
                                </Trigger>
                                <MultiTrigger>
                                  <MultiTrigger.Conditions>
                                    <Condition Property="IsMouseOver" Value="True"/>
                                    <Condition Property="IsChecked" Value="True"/>
                                  </MultiTrigger.Conditions>
                                  <Setter Property="Stroke" TargetName="ExpandPath" Value="#FF262626"/>
                                  <Setter Property="Fill" TargetName="ExpandPath" Value="#FF595959"/>
                                </MultiTrigger>
                              </ControlTemplate.Triggers>
                            </ControlTemplate>
                          </Setter.Value>
                        </Setter>
                      </Style>
                    </ToggleButton.Style>
                  </ToggleButton>
                  <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="1" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True">
                    <ContentPresenter x:Name="PART_Header" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                  </Border>
                  <ItemsPresenter x:Name="ItemsHost" Grid.ColumnSpan="2" Grid.Column="1" Grid.Row="1"/>
                </Grid>
                <ControlTemplate.Triggers>
                  <Trigger Property="IsExpanded" Value="False">
                    <Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/>
                  </Trigger>
                  <Trigger Property="HasItems" Value="False">
                    <Setter Property="Visibility" TargetName="Expander" Value="Hidden"/>
                  </Trigger>
                  <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                  </Trigger>
                  <MultiTrigger>
                    <MultiTrigger.Conditions>
                      <Condition Property="IsSelected" Value="True"/>
                      <Condition Property="IsSelectionActive" Value="False"/>
                    </MultiTrigger.Conditions>
                    <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>
                  </MultiTrigger>
                  <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                  </Trigger>
                </ControlTemplate.Triggers>
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </TreeView.ItemContainerStyle>
    </TreeView>
</Grid>

1 个答案:

答案 0 :(得分:1)

试试这个模板:

<TreeView x:Name="TreeView" ItemTemplateSelector="{StaticResource NodeTypeTemplateSelector}">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TreeViewItem}">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition MinWidth="19" Width="Auto"/>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                            <ToggleButton x:Name="Expander" ClickMode="Press"
                                                  IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}">
                                <ToggleButton.Style>
                                    <Style TargetType="{x:Type ToggleButton}">
                                        <Setter Property="Focusable" Value="False"/>
                                        <Setter Property="Width" Value="16"/>
                                        <Setter Property="Height" Value="16"/>
                                        <Setter Property="Template">
                                            <Setter.Value>
                                                <ControlTemplate TargetType="{x:Type ToggleButton}">
                                                    <Border Background="Transparent" Height="16" Padding="5" Width="16">
                                                        <Path x:Name="ExpandPath" Data="M0,0 L0,6 L6,0 z" Fill="Transparent" Stroke="#FF989898">
                                                            <Path.RenderTransform>
                                                                <RotateTransform Angle="135" CenterY="3" CenterX="3"/>
                                                            </Path.RenderTransform>
                                                        </Path>
                                                    </Border>
                                                    <ControlTemplate.Triggers>
                                                        <Trigger Property="IsChecked" Value="True">
                                                            <Setter Property="RenderTransform" TargetName="ExpandPath">
                                                                <Setter.Value>
                                                                    <RotateTransform Angle="180" CenterY="3" CenterX="3"/>
                                                                </Setter.Value>
                                                            </Setter>
                                                            <Setter Property="Fill" TargetName="ExpandPath" Value="#FF595959"/>
                                                            <Setter Property="Stroke" TargetName="ExpandPath" Value="#FF262626"/>
                                                        </Trigger>
                                                        <Trigger Property="IsMouseOver" Value="True">
                                                            <Setter Property="Stroke" TargetName="ExpandPath" Value="#FF1BBBFA"/>
                                                            <Setter Property="Fill" TargetName="ExpandPath" Value="Transparent"/>
                                                        </Trigger>
                                                        <MultiTrigger>
                                                            <MultiTrigger.Conditions>
                                                                <Condition Property="IsMouseOver" Value="True"/>
                                                                <Condition Property="IsChecked" Value="True"/>
                                                            </MultiTrigger.Conditions>
                                                            <Setter Property="Stroke" TargetName="ExpandPath" Value="#FF262626"/>
                                                            <Setter Property="Fill" TargetName="ExpandPath" Value="#FF595959"/>
                                                        </MultiTrigger>
                                                    </ControlTemplate.Triggers>
                                                </ControlTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </ToggleButton.Style>
                            </ToggleButton>
                            <Border Name="Bd" Grid.Column="1" Background="{TemplateBinding Control.Background}"
                                        BorderBrush="{TemplateBinding Control.BorderBrush}"
                                        BorderThickness="{TemplateBinding Control.BorderThickness}"
                                        Padding="{TemplateBinding Control.Padding}" SnapsToDevicePixels="true">
                                <ContentPresenter x:Name="PART_Header" ContentSource="Header"
                                            HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
                                            SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"/>
                            </Border>
                            <ItemsPresenter x:Name="ItemsHost" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="TreeViewItem.IsExpanded" Value="false">
                                <Setter TargetName="ItemsHost" Property="UIElement.Visibility" Value="Collapsed"/>
                            </Trigger>
                            <Trigger Property="ItemsControl.HasItems" Value="false">
                                <Setter TargetName="Expander" Property="UIElement.Visibility" Value="Hidden"/>
                            </Trigger>
                            <Trigger Property="TreeViewItem.IsSelected" Value="true">
                                <Setter TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"
                                                Property="Border.Background"/>
                                <Setter Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"
                                                Property="Control.Foreground"/>
                            </Trigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="TreeViewItem.IsSelected" Value="true"/>
                                    <Condition Property="TreeViewItem.IsSelectionActive" Value="false"/>
                                </MultiTrigger.Conditions>
                                <Setter TargetName="Bd"
                                                Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"
                                                Property="Border.Background"/>
                                <Setter Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"
                                                Property="Control.Foreground"/>
                            </MultiTrigger>
                            <Trigger Property="UIElement.IsEnabled" Value="false">
                                <Setter Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" Property="Control.Foreground"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="VirtualizingPanel.IsVirtualizing" Value="true">
                    <Setter Property="ItemsControl.ItemsPanel">
                        <Setter.Value>
                            <ItemsPanelTemplate>
                                <VirtualizingStackPanel/>
                            </ItemsPanelTemplate>
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>