2011-07-25 16 views
5

インターネット上で見つかった2つの例をマージしています。 1つは約stretched selection stylesであり、1つは約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; 
    } 
} 

このメソッドは、ツリー内のツリービューアイテムの深さを取得しようとします。問題は: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'sをツリーに追加すると、親子関係がありますか? – Marnix

+0

これは、DataTemplate内のParentプロパティに関する別の投稿です。 http://stackoverflow.com/questions/3255365/wpf-binding-parent-property-in-hierarchicaldatatemplate しかし、ビジュアルツリーのスキャンも*最善の方法ではありません。最も信頼性の高い方法は、ツリーが階層モデルの視覚的表現であるため、モデルから深さを取得することです。ビジュアルツリーは信頼できませんでした。たとえば、階層のフィルタリングされたビュー(視覚的な変更は考えますが、深さは同じままです)と考えてください。 –

+0

はい、それをモデルに入れる方が簡単ですが、どのようにスタイルを指定することができますか?私の最初のチュートリアルでは、ツリービューのデフォルトのスタイルをオーバーライドしています。どのようにしてモデルをスタイルの中で使うことができますか? – Marnix

関連する問題