上一篇中我们用数据驱动界面的方式使用了TreeView。这一篇我们稍稍改一改TreeView的样式。把TreeView表示节点可以展开的小三角替换成Expander是个不错的开始。既能复习TreeView的可视化树,又避免步子太大扯到蛋。
自定义TreeView样式
回顾一下,TreeView中我们所看到的所有Item,都是TreeViewItem负责呈现的。因此,我们需要重现实现TreeViewItem的Template。TreeViewItem要负责展示Item的内容,所以Template里应该要有一个ContentPreserenter;TreeViewItem自身也是个ItemsControl,Template里也应有一个ItemsPreserenter。除此之外就是表示Item是否可以展开的小三角,即我们要换成Expander的部分。
结合图片分析一下TreeViewItem的可视化树。首先应有两行,第一行显示当前Item,第二行显示下一级Item;
其次应有两列,第一列放置小三角,第二列展示内容。应该是这样的结构:
|-|Column1|Column2|
|———-|———-|———-|
|Row1|Expander|ContentPreserenter|
|Row2|/|ItemsPreserenter|
跟其他控件不一样的是,在设计TreeViewItem的模板时,要先不管ItemsPreserenter那部分,就像它已经做好了一样。待到把其余部分的结构都定下来了,ItemsPreserenter部分自然就如愿了。这有实际上就是递归:ItemsPreserenter里有TreeViewItem的模板需要展开,这跟当前所做的问题,即重新实现TreeViewItem的模板,是一样的。我们在ItemsPreserenter的问题已经解决的假设上,解决了TreeViewItem的模板。这像极了汉诺塔。
习惯了这样的递归思考后,把几个显示隐藏的小细节处理好,这就得到了下面的XAML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <Style TargetType="TreeViewItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="TreeViewItem"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="24"></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="*"></RowDefinition> </Grid.RowDefinitions> <Expander IsExpanded="{Binding RelativeSource={RelativeSource TemplatedParent},Path=IsExpanded,Mode=TwoWay}" x:Name="expander"></Expander> <ContentPresenter VerticalAlignment="Center" Grid.Column="1" ContentSource="Header"></ContentPresenter> <ItemsPresenter Visibility="{Binding RelativeSource={RelativeSource TemplatedParent},Path=IsExpanded,Converter={StaticResource BoolToVisibilityConverter}}" Grid.Row="1" Grid.Column="1"></ItemsPresenter> </Grid> <ControlTemplate.Triggers> <Trigger Property="HasItems" Value="False"> <Setter TargetName="expander" Property="Visibility" Value="Collapsed"></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
|
大功告成!
源代码参见
https://github.com/Verrickt/Melchior-Sample/tree/master/FluentTreeView_Part3