如何拉伸TreeViewItem宽度来填充父级?

时间:2017-11-13 07:20:18

标签: wpf treeview

我有一个WPF TreeView,我想将TreeViewItem像其父级一样扩展到整个空间。

<TreeView Name="treeFamilies" AllowDrop="True" >
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type local:MyNode}" ItemsSource="{Binding Members}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" Background="LightGray"/>
                <TextBlock Text=" [" Foreground="Blue" Background="LightGray"/>
                <TextBlock Text="{Binding Members.Count}" Foreground="Blue" Background="LightGray"/>
                <TextBlock Text="]" Foreground="Blue" Background="LightGray" />
            </StackPanel>
        </HierarchicalDataTemplate>
    </TreeView.Resources>
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

我似乎错误地使用了ItemContainer样式<Setter Property="HorizontalContentAlignment" Value="Stretch"/>。我现在的树看起来像这张照片:

pic1

我想要拉伸灰色背景以填充树视图控件的整个末尾。 我怎么能做到这一点?

3 个答案:

答案 0 :(得分:2)

Il Vic的评论this msdn blog显示了一种类似于 hack 的方式,用于从TreeViewItem中删除最后一列。

万一博客被关闭,我将工作代码复制到这里。加载TreeViewItem后,我从网格中删除了第三个ColumnDefinition,并将第二个ColumnDefinition的宽度设置为*;

public class StretchingTreeViewItem : TreeViewItem
{
    public StretchingTreeViewItem()
    {
        this.Loaded += new RoutedEventHandler(StretchingTreeViewItem_Loaded);
    }

    private void StretchingTreeViewItem_Loaded(object sender, RoutedEventArgs e)
    {
        if (this.VisualChildrenCount > 0)
        {
            Grid grid = this.GetVisualChild(0) as Grid;
            if (grid != null && grid.ColumnDefinitions.Count == 3)
            {
                grid.ColumnDefinitions.RemoveAt(2);
                grid.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Star);
            }
        }
    }

    protected override DependencyObject GetContainerForItemOverride()
    {
        return new StretchingTreeViewItem();
    }

    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return item is StretchingTreeViewItem;
    }
}

然后我覆盖TreeView以获得自定义项目。

public class StretchingTreeView : TreeView
{
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new StretchingTreeViewItem();
    }

    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return item is StretchingTreeViewItem;
    }        
}

答案 1 :(得分:0)

您必须覆盖treeview itemcontainerstyle的模板,这与Microsoft有点奇怪,但是您必须重新编写整个模板。因此,将没有扩展器或类似的东西,但是使用此代码,您的树视图项目将遍及整个父级。我将IsExpanded设置为true,以便仍然显示您的孩子。

<div class="wrapper">

 <div class="container">
   <div class="svg"></div>
   <p>lorem</p>
 </div>

 <div class="container">
  <div class="svg"></div>
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam. </p>
 </div>

</div>

如果您想保持正常的行为,例如看一下本教程中的“扩展”按钮,它将帮助您重写整个模板: https://wpf.2000things.com/2017/09/23/1218-stretching-items-in-treeview-across-entire-control/

答案 2 :(得分:0)

我想出了一个非常简单的方法来实现这个(虽然也不完美):绑定到树视图的 ActualWidth 属性

<TreeView x:Name="ListUI">
  <TreeView.Resources>
    <DataTemplate>
      <Grid HorizontalAlignment="Stretch"
        Width="{Binding ActualWidth,
          ElementName=ListUI,
          Converter={StaticResource MinusFortyFiveConverter}}">
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="Auto" />
          <ColumnDefinition Width="*" />
          <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="0" Text="Left Side" />
        <!-- Will gap in the middle -->
        <TextBlock Grid.Column="2" Text="Right Side" />
      </Grid>
    </DataTemplate>
  </TreeView.Resources>
</TreeView>

您可能需要一个将数字减少 10 左右的值转换器,否则它会太宽,请根据您的皮肤需要进行调整。我对默认皮肤的初步测试是 - 45 是一个不错的起点。

public class MinusFortyFiveConverter : IValueConverter
{
    /// <inheritdoc/>
    public object Convert(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (double)value - 45;
    }

    /// <inheritdoc/>
    public object ConvertBack(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException("Cannot convert back");
    }
}