Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stretch TreeViewItem width to fill parent?

Tags:

wpf

treeview

I have a WPF TreeView and I want to stretch the TreeViewItem to the entire space like its parent.

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

It seems I'm using the ItemContainer style <Setter Property="HorizontalContentAlignment" Value="Stretch"/> wrongly. My current tree is looking like this picture:

pic1

I want tho strech the gray background to fill the entire end of the treeview control. How could I achieve this?

like image 693
Dia Avatar asked Nov 13 '17 07:11

Dia


2 Answers

Form Il Vic's comment, this msdn blog shows a hack-like way to remove the last column from TreeViewItem.

In case the blog shut down, I copy my working code here. After a TreeViewItem is loaded, I remove the 3rd ColumnDefinition from the grid, and set 2nd ColumnDefinition width to *;

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;
    }
}

Then I override TreeView to get the custom items.

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

    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return item is StretchingTreeViewItem;
    }        
}
like image 84
Dia Avatar answered Nov 07 '22 17:11

Dia


You have to overwrite the template of the treeview itemcontainerstyle, a bit odd from microsoft but you have to write the whole template new. So there will be no expander or anything like that, but with this code your treeview items will be stretch over the whole parent. I set IsExpanded true so your childs are still shown.

<TreeView Margin="10"
              ItemsSource="{Binding ChainedCommandVMs}">
        <TreeView.ItemContainerStyle>
            <Style TargetType="{x:Type TreeViewItem}">
                <Setter Property="IsExpanded"
                        Value="True" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="TreeViewItem">
                            <StackPanel>
                                <ContentPresenter ContentSource="Header" />
                                <ItemsPresenter Name="ItemsHost" />
                            </StackPanel>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </TreeView.ItemContainerStyle>...

If you want to keep the normal behavior, like the expand button look at this tutorial it will help you to rewrite the whole template: https://wpf.2000things.com/2017/09/23/1218-stretching-items-in-treeview-across-entire-control/

like image 42
Momo Avatar answered Nov 07 '22 17:11

Momo