WPF TreeViewItem控件的高度模板不折叠

时间:2015-11-04 14:31:40

标签: wpf user-controls treeview treeviewitem

我有一个问题,我一直试图解决一个星期,并不仅广泛尝试解决这个问题,但已经在StackOverFlow和其他网站上进行了大量关于如何解决这个问题的研究。为了清楚起见,我已经学习了大约3个月左右的WPF并且来自WinForms并且仍处于学习阶段。

这是我的问题。

我有一个TreeViewItems,我将其添加到TreeView控件中。这些TreeView项目使用Style创建我想要完成的自定义外观,这几乎就是整个应用程序的外观和感觉。 Style使用针对Template属性的显式Setter.Value来创建TreeView项的自定义外观。它有自己的自定义扩展箭头,绑定到TreeViewItem头的TextBlock标头,当然还有ContentPresenter和ItemsPresenter。还有一个触发器连接到TreeViewItem的IsExpanded值的值,这样在TreeViewItem展开或折叠时可以显示或隐藏ItemsPresenter。除了崩溃和扩展部分外,一切都正常。当然,ItemsPresenter隐藏并显示它应该如此,但是当IsExpanded为false时,TreeViewItem本身实际上不会折叠它的高度。为了表明我的意思,这里有两张图片来说明发生了什么。我在样式的模板中在网格周围添加了一个绿色边框,以显示单个TreeViewItem本身在折叠时不会缩小其“高度”。

扩展

Pic of expanded tree view item

折叠

Pic of collapsed tree view item

如您所见,绿色边框或树视图项本身在折叠时仍然与展开时的高度相同。这是用于创建TreeViewItem自定义样式的XAML。

TreeViewItem样式XAML代码:

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

以下代码是我使用样式的方式

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

感谢任何人提供的任何输入或帮助。我希望我足够清楚。

1 个答案:

答案 0 :(得分:0)

我明白了。我所做的只是在IsExpanded触发器中添加一个setter来设置ItemsPresenter所在的网格行的属性。我所做的就是将行的高度设置为0,这基本上隐藏了项目。以下是上述代码中触发器本身的代码,并应用了更改。

{{1}}

我感兴趣的是,如果有其他人有更好的解决方案。在我想出这个之后,我想到了动画行的高度直到它为0才能产生更好的效果,但是没有成功。我发现StoryBoards是freezable并且在Style或ControlTemplate内部被冻结。这意味着如果你想要它的动画,那么项目折叠的动画必须用后面的代码实现,或者在每个TreeViewItem上单独实现?我相信有更好的方法。如果我发现如何完成这个,我会更新这篇文章供大家参考。请随时在这篇文章中添加更好的解决方案!!