2011-07-25 79 views
5

我正在合併在互聯網上找到的兩個示例。一個關於stretched selection styles和一個關於multi-selection in a treeview在WPF中的HierarchicalDataTemplate中獲取TreeViewItem的父項

我有一切工作,除了樹視圖的縮進。我可以給我所有的代碼,但那不會解決它。

我的問題主要表現在以下方法:

public static class TreeViewItemExtensions 
{ 
    public static int GetDepth(this TreeViewItem item) 
    { 
     FrameworkElement elem = item; 
     while (elem.Parent != null) 
     { 
      var tvi = elem.Parent as TreeViewItem; 
      if (tvi != null) 
       return tvi.GetDepth() + 1; 
      elem = elem.Parent as FrameworkElement; 
     } 
     return 0; 
    } 
} 

該方法嘗試檢索樹中的一個TreeViewItem的深度。問題是:elem.Parent總是null。其結果深度爲0.

我認爲這是發生的,因爲我使用的是HierarchicalDataTemplate。我的xaml的一部分看起來像這樣。

<TreeView Name="folderTree" 
      ItemsSource="{Binding Folders}" 
      SelectedItemChanged="folderTree_SelectedItemChanged" 
      HorizontalContentAlignment="Stretch"> 

    <TreeView.ItemTemplate> 
     <HierarchicalDataTemplate ItemsSource="{Binding Folders}" 
            DataType="{x:Type Model:IFolder}"> 

      <StackPanel Orientation="Horizontal"> 
       <StackPanel.Style> 
        <Style TargetType="{x:Type StackPanel}"> 
         <Style.Triggers> 
          <DataTrigger Binding="{Binding IsSelected}" 
             Value="True"> 
           <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> 
          </DataTrigger> 
         </Style.Triggers> 
        </Style> 
       </StackPanel.Style> 

       <Image Source="{Binding Converter={StaticResource iconConverter}}" Height="{Binding ElementName=theFile,Path=ActualHeight}"/> 
       <TextBlock Text="{Binding FileName}" Name="theFile"/> 
      </StackPanel> 
     </HierarchicalDataTemplate> 
    </TreeView.ItemTemplate> 
</TreeView> 

的XAML我的樹視圖的風格是這樣的:

<Style x:Key="{x:Type TreeViewItem}" TargetType="{x:Type TreeViewItem}"> 

    <!-- leaving some stuff out here --> 

    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type TreeViewItem}"> 

       <ControlTemplate.Resources> 
        <local:LeftMarginMultiplierConverter Length="19" x:Key="lengthConverter" /> 
       </ControlTemplate.Resources> 

       <StackPanel> 
        <!-- The upper part of the TreeViewItem --> 
        <Border Name="Bd" 
          Background="{TemplateBinding Background}" 
          BorderBrush="{TemplateBinding BorderBrush}" 
          BorderThickness="{TemplateBinding BorderThickness}" 
          Padding="{TemplateBinding Padding}"> 

         <!-- The margin is what we try to measure, how can we get the parents from the templatedParents? --> 
         <Grid Margin="{Binding Converter={StaticResource lengthConverter}, 
               RelativeSource={RelativeSource TemplatedParent}, 
               Path=.}"> 

          <Grid.ColumnDefinitions> 
           <ColumnDefinition Width="19" /> 
           <ColumnDefinition /> 
          </Grid.ColumnDefinitions> 

          <ToggleButton x:Name="Expander" 
              Style="{StaticResource ExpandCollapseToggleStyle}" 
              IsChecked="{Binding Path=IsExpanded, 
                 RelativeSource={RelativeSource TemplatedParent}}" 
              ClickMode="Press"/> 

          <ContentPresenter x:Name="PART_Header" 
               Grid.Column="1" 
               ContentSource="Header" 
               HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/> 
         </Grid> 
        </Border> 

        <!-- the children of the TreeViewItem --> 
        <ItemsPresenter x:Name="ItemsHost" /> 
       </StackPanel> 

       <!-- leaving some stuff out here with triggers --> 

      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

我怎樣才能讓HierarchicalDataTemplate填補Parent財產?

回答

7

我會掃描視覺樹代替。

下面是一個簡單的(甚至不那麼優雅)溶液:

public static class TreeViewItemExtensions 
{ 
    public static int GetDepth(this TreeViewItem item) 
    { 
     DependencyObject target = item; 
     var depth = 0; 
     while (target != null) 
     { 
      if (target is TreeView) 
       return depth; 
      if (target is TreeViewItem) 
       depth++; 

      target = VisualTreeHelper.GetParent(target); 
     } 
     return 0; 
    } 
} 

乾杯。

+0

我見過這個。但是,怎麼會,當我通常將TreeViewItem添加到樹中時,*有*父/子關係? – Marnix

+0

這是另一篇關於DataTemplate中Parent屬性的回覆: http://stackoverflow.com/questions/3255365/wpf-binding-parent-property-in-hierarchicaldatatemplate 但是,即使對可視化樹的掃描是*不*最好的方法。最可靠的方法是從模型中獲取深度,僅僅是因爲樹是分層模型的可視化表示。視覺樹不可靠。例如,考慮到層次結構的過濾視圖:視覺變化,但深度保持不變。 –

+0

是的,它似乎更容易放在模型中,但我怎樣才能在我的風格中指定?我參考的第一個教程覆蓋了treeview的默認樣式。如何在風格中使用模型? – Marnix