在WPF中的HierarchicalDataTemplate中获取TreeViewItem的父级

时间:2011-07-25 14:58:18

标签: c# wpf xaml treeviewitem

我正在合并在互联网上找到的两个例子。一个约stretched selection styles,一个约multi-selection in a treeview

除了树视图的缩进外,我还能正常工作。我可以提供所有代码,但这不会解决它。

我的问题在于以下方法:

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属性?

1 个答案:

答案 0 :(得分: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;
    }
}

干杯。