How to stretch TreeViewItem width to fill parent? How to stretch TreeViewItem width to fill parent? wpf wpf

How to stretch TreeViewItem width to fill parent?


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


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/


I figured out a very simple way to implement this (though not perfect either): bind to the tree view's ActualWidth property

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

You will probably need a value converter that reduces the number by 10 or so or it will be too wide, adjust as you need it for your skin. My initial test with default skin was that minus 45 was a good starting place.

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