2017-02-20 2 views
1

У меня есть WPF TreeView, для которого я указал два HierarchicalDataTemplates, и я использую селектор шаблонов, чтобы выбрать, какой из них применять на основе типа в связанном с данными объекте. Шаблоны иерархических данных применяются, и я вижу ожидаемые имена элементов в TreeView.WPF TreeView: Использование ItemTemplateSelector и ItemContainerStyle не работает в то же время

Однако, когда я пытаюсь установить ItemContainerStyle для элементов дерева, то похоже, что иерархические шаблоны данных больше не применяются: метка для каждого элемента представления дерева устанавливается в имя класса объекта, связанный с. Стиль, который я применяю, задает шаблон для TreeViewItemControlTemplate (у меня есть планы немного изменить этот шаблон, но пока я использую неизмененный, который я экспортировал из 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

Попробуйте этот шаблон:

<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> 
+0

Нужно ли добавлять триггер для свойства VirtualizingPanel.IsVirtualizing? Я думал, что просто смогу установить свойство VirtualizingPanel.IsVirtualising в TreeView. – randusr836

+0

Я опубликовал рабочий шаблон по умолчанию. Вы можете изменить его в соответствии с вашим требованием. Локальные значения имеют приоритет над значениями, заданными установщиками стилей. – mm8

Смежные вопросы