3

I am new to WPF forms and I ran across an issue when trying to set a background in a TreeViewItem.

<Window x:Class="wpf_test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <!--Styles-->
        <Style x:Key="GUIEntity" TargetType="{x:Type Control}">
            <Setter Property="MinWidth" Value="150" />
            <Setter Property="MaxWidth" Value="150" />
        </Style>
        <Style TargetType="TreeViewItem">
            <Setter Property="IsExpanded" Value="True" />
        </Style>
        <!--Data Sources-->
        <x:Array x:Key="BooleanListData" Type="sys:String" xmlns:sys="clr-namespace:System;assembly=mscorlib">
            <sys:String>True</sys:String>
            <sys:String>False</sys:String>
        </x:Array>
    </Window.Resources>
    <Grid>
        <TreeView Name="treeView1" Margin="5" Background="Azure">
            <TreeViewItem Header="ComplexTypeProperty" Margin="5">
                <CheckBox Style="{StaticResource GUIEntity}" Margin="3,3,10,3" Content="Instance" />
                <StackPanel Orientation="Horizontal" Background="LightGray">
                    <Label Margin="0,2,0,0" Content="IsBoolProperty" Width="150" />
                    <ComboBox Margin="5" Style="{StaticResource GUIEntity}" ItemsSource="{StaticResource BooleanListData}" />
                </StackPanel>
            </TreeViewItem>
        </TreeView>
    </Grid>
</Window>

The problem is that the background being set in the StackPanel doesn't go the full width (to the right) of the TreeView control. I tried adding HorizontalAllignment="Stretch" to all the controls from the TreeView down but it had no effect. The width of the background on the StackPanel goes only to the end of the ComboBox.

By setting a background on the TreeView I confirmed that it did take up the full width of the form so that wouldn't be the issue.

Does anyone know how to extend the background to the end of the TreeView's size?

How would i go about overriding this grid in the simplest way?

zastrowm
  • 8,017
  • 3
  • 43
  • 63
  • I guess this post covers your question: http://stackoverflow.com/questions/15826637/wpf-treeview-item-background-over-entire-row 'code' – Georgy Smirnov May 04 '13 at 12:38
  • @GeorgySmirnov that just sets the background on the header. It seams to have no effect on anything else. And the header's background only extends to the text and not full width. (Also i didn't want the width to extend to the left, only the right). – gankstaman the first May 04 '13 at 12:45
  • From what I see I think I would want to do a `Grid.ColumnSpan="2"` on the highlighted grid and that would do what I want. But how do I do that? – gankstaman the first May 05 '13 at 00:17

2 Answers2

1

Here is a blog post that covers problem and gives a solution. As far as I remember, it worked ok for me. Basically you need to retemplate TreeViewItem. Lot of Xaml but I think is the only proper solution

https://leecampbell.com/2009/01/14/horizontal-stretch-on-treeviewitems/

Blair
  • 6,623
  • 1
  • 36
  • 42
Jurica Smircic
  • 6,117
  • 2
  • 22
  • 27
0

This is just to extend this old post with some visuals.

Issue statement: cannot right-align content in TreeView by default -based on some other comments here&there - I tested to remove any stackpanels from the Xaml (yet it is not the issue as I can replicate the desired design outside of TreeView with stackpanels)

TLDR: Workarounds are posted in previous comments

The XAML:

<Window x:Class="Test"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:DbSeeder.WPF.View"
    mc:Ignorable="d"
    Title="Test" 
    Height="450" 
    Width="800"
    Loaded="Window_Loaded">
<DockPanel>
    <!-- what i want -->
    <StackPanel DockPanel.Dock="Top"
                Margin="5">
        <Label Content="This is the expected structure" 
               FontFamily="Verdana"
               FontWeight="Bold"
               BorderBrush="Black"
               BorderThickness="2"
               HorizontalAlignment="Stretch"
               Background="Orange"
               />
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="5*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <!-- Buttons -->
            <StackPanel Grid.Column="1" 
                        Orientation="Horizontal" 
                        HorizontalAlignment="Right"
                        Margin="3">
                <Button Content="Button 1"
                        Margin="5"/>
                <Button Content="Button 2"
                        Margin="3"/>
            </StackPanel>

            <!-- Keys -->
            <StackPanel Grid.Column="0"
                        Orientation="Horizontal"
                        HorizontalAlignment="Left"
                        Margin="3" >
                <Label Content="Here should come key 1" Margin="3" BorderBrush="Black" BorderThickness="2"/>
                <Label Content="Here should come key 2" Margin="3" BorderBrush="Black" BorderThickness="2"/>
            </StackPanel>
        </Grid>
    </StackPanel>

    <!-- What I get 2-->
    <Grid 
        ShowGridLines="True"
        DockPanel.Dock="Top"
        Margin="5">

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <Label Content="This is what I get" 
               FontFamily="Verdana"
               FontWeight="Bold"
               BorderBrush="Black"
               BorderThickness="2"
               Background="Orange"
               Grid.Column="0"
               Grid.Row="0"/>
        <TreeView x:Name="alternative2"
                  Grid.Column="0"
                  Grid.Row="1"
                  HorizontalContentAlignment="Stretch"
                  HorizontalAlignment="Stretch">
            <TreeView.Resources>
                <Style TargetType="{x:Type TreeViewItem}">
                    <Setter Property="HeaderTemplate">
                        <Setter.Value>
                            <DataTemplate>
                                    <Grid ShowGridLines="True"
                                          DockPanel.Dock="Top"
                                          Margin="5">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="3*"/>
                                            <ColumnDefinition Width="3*"/>
                                            <ColumnDefinition Width="*"/>
                                            <ColumnDefinition Width="*"/>
                                        </Grid.ColumnDefinitions>
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>

                                        <!-- Buttons -->
                                        <Button Content="Button 1"
                                                Grid.Column="2" 
                                                Margin="5"
                                                HorizontalAlignment="Stretch"/>
                                        <Button Content="Button 2"
                                                Grid.Column="3" 
                                                Margin="3"
                                                HorizontalAlignment="Stretch"/>

                                        <!-- Keys -->

                                        <Label Grid.Column="0" 
                                               HorizontalAlignment="Stretch" 
                                               Content="Here should come key 1" 
                                               Margin="3" 
                                               BorderBrush="Black" 
                                               BorderThickness="2"/>
                                        <Label Grid.Column="1"
                                               HorizontalAlignment="Stretch" 
                                               Content="Here should come key 2" 
                                               Margin="3" 
                                               BorderBrush="Black" 
                                               BorderThickness="2"/>
                                    </Grid>
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </TreeView.Resources>
        </TreeView>
    </Grid>
</DockPanel>

And the code behind (to seed the view)

public partial class Test : Window
{
    protected IDictionary<string, object> JsonFields { get; set; }

    public Test()
    {
        InitializeComponent();
        var x = new Dictionary<string, string>()
        {
            {"key 1", "string" },
            {"key 2", "string 2" }
        };

        var y = new List<string>()
        {
            "subList5a",
            "subList5b",
        };

        JsonFields = new Dictionary<string, object>()
        {
            { "Key 1", "string" },
            { "Key 2", "string" },
            { "Key 3", "string" },
            { "Key 4 - dict", x },
            { "Key 5 - List", y }
        };
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        var counter = 0;
        foreach (var key in JsonFields.Keys)
        {
            counter++;

            var item = new TreeViewItem()
            {
                Header = key,
                ClipToBounds = true
            };

            if (counter % 2 == 0)
            {
                var subItem = new TreeViewItem()
                {
                    Header = $"SubKey of {item.Header}",
                    ClipToBounds = true
                };

                item.Items.Add(subItem);
            }
            alternative2.Items.Add(item);
        }
    }
}

Issue example

Neophyte
  • 132
  • 1
  • 8