0
votes

I have an issue that I have been trying to solve for a week and have not only played around extensively trying to figure this out but have done lots of research on StackOverFlow and other websites on how to fix this problem. Just to be clear, I have been learning WPF for about 3 or so months and come from WinForms and am still in the learning phase.

Here is my problem.

I have a TreeViewItems that I am adding to a TreeView control. These TreeView items use a Style that creates a custom look that I am trying to accomplish that is pretty much the look and feel of the entire application. The Style uses an explicit Setter.Value against the Template property to create the custom look of the TreeView item. It has its own custom expander arrow, TextBlock header that is bound to the TreeViewItem header, and also of course a ContentPresenter and a ItemsPresenter. There is also a trigger that is wired up to the value of the TreeViewItem's IsExpanded value so that way the ItemsPresenter can be shown or hidden when the TreeViewItem is expanded or collapsed. Everything works as it should except the collapse and expand part. Of course the ItemsPresenter hides and shows like it should but the TreeViewItem itself does not actually collapse its height when the IsExpanded is false. To show what I mean, here are 2 pictures to illustrate what is going on. I added a green border around the grid in the template of the style to show that the individual TreeViewItem itself is not shrinking its "height" when collapsed.

Expanded

Pic of expanded tree view item

Collapsed

Pic of collapsed tree view item

As you can see, the green border, or the treeview item itself is still the same height when collapsed as it is when expanded. Here is the XAML used to create the custom style of the TreeViewItem's themselves.

TreeViewItem Style XAML Code:

<Style x:Key="TreeViewItemStyle" TargetType="TreeViewItem">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TreeViewItem">
                <Border x:Name="MyBorder" BorderThickness="1" BorderBrush="LawnGreen">
                    <Grid HorizontalAlignment="Left" ShowGridLines="True">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="25"></RowDefinition>
                            <RowDefinition Height="Auto"></RowDefinition>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="20"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                        </Grid.ColumnDefinitions>

                        <ui:TreeViewItemExpander x:Name="TreeViewItemExpander" Grid.Row="0" Grid.Column="0" IsPointingDown="{TemplateBinding IsExpanded}"/>

                        <!--This represents the text for the tree view item itself-->
                        <TextBlock Text="{TemplateBinding Header}" Grid.Row ="0" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Center" Foreground="White"/>

                        <ContentPresenter x:Name="ContentPresenter" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top"/>

                        <ItemsPresenter x:Name="ItemsPresenter" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" Visibility="Hidden"/>
                    </Grid>
                </Border>

                <ControlTemplate.Triggers>
                    <Trigger Property="IsExpanded" Value="True">
                        <Setter TargetName="ItemsPresenter" Property="Visibility" Value="Visible"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

This code below is how I am using the style

        <TreeView Style="{StaticResource TreeViewStyle}" Width="200" Margin="419,337,19,328">
        <controls:CustomTreeViewItem Header="Folder 1" Style="{StaticResource TreeViewItemStyle}">
            <Button Content="Item 1" HorizontalAlignment="Left" VerticalAlignment="Top" Height="20"/>
            <Button Content="Item 2" HorizontalAlignment="Left" VerticalAlignment="Top" Height="20"/>
        </controls:CustomTreeViewItem>
    </TreeView>

Thanks for any input or help that anybody can provide. I hope that I was clear enough.

1
@Emmanuel DURIN Thanks for the edit. I am new to posting on stackoverflow.Calvin Wilkinson
You re welcome. Your post is of pretty good quality - even if it's long - it 's still comfortable reading it (pictures, code excerpts, paragraphs, good English).Emmanuel DURIN

1 Answers

0
votes

I figured it out. What I did was just add a setter in the IsExpanded trigger to set the property of the grid row that the ItemsPresenter resides in. All I did was set the height of the row to 0 which essentially hides the items. Here is the code of the trigger itself from the code above with the change applied.

                            <ControlTemplate.Triggers>
                            <Trigger Property="IsExpanded" Value="True">
                                <Setter TargetName="Items" Property="Visibility" Value="Visible"/>
                                <Setter TargetName="ItemsRow" Property="Height" Value="0"/>
                            </Trigger>
                        </ControlTemplate.Triggers>

I am interested though if anybody else has a better solution. After I figured this out, I then thought about animating the height of the row until it is 0 to give a better effect, but was not successful. I found out that StoryBoards are freezable and are frozen when inside of a Style or ControlTemplate. That means if you wanted it to be animated, then the animation of the item collapsing would have to be implemented with code behind, or on each TreeViewItem individually? I am sure there is a better way. If I find out how to accomplish this, I will update this post for everybody to reference. Please feel free to add to this post on a better solution!!