前面一片文章实现TreeView的基本的模板重写,那么照着这个思路,我们再来写一个稍稍复杂的TreeView ,其它的内容都和前面系列内容相似,还是和之前文章介绍的一样,首先看看做出的DEMO的最终样式,先来一睹为快。

其实并不复杂,关键的是要准确去理解TreeView这个控件,这个控件的核心是TreeViewItem,那么我们就重点来看看这个样式该怎么写。

 <Style TargetType="{x:Type TreeViewItem}">
<Setter Property="Background" Value="Transparent"/>
<!--此处设置TreeViewItem的绑定样式-->
<Setter Property="IsExpanded" Value="True"></Setter>
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
<Setter Property="Padding" Value="1,0,0,0"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True" Margin="10"></StackPanel>
</ItemsPanelTemplate>
</Setter.Value>
</Setter> <Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="19"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="22"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="#00a3d9"
Grid.Row="0"
Grid.Column="1"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="true"
MaxWidth="300"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<ContentPresenter x:Name="PART_Header"
ContentSource="Header"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<Rectangle x:Name="VerLn" Grid.Row="1" Grid.Column="1" Width="1" Stroke="Green" HorizontalAlignment="Center" VerticalAlignment="Stretch" Height="50" SnapsToDevicePixels="true" Fill="White"/>
<Border x:Name="itemsBorder"
BorderBrush="#00a3d9"
BorderThickness="1"
Padding="2"
Margin="10,0,10,0"
Grid.ColumnSpan="3"
Grid.Column="0"
Grid.Row="2"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<ItemsPresenter x:Name="ItemsHost" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter Property="Visibility" TargetName="ItemsHost" Value="Collapsed"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="VerLn" Value="0"/>
<Setter Property="Height" TargetName="itemsBorder" Value="0"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="VirtualizingStackPanel.IsVirtualizing" Value="true">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>

  在这里我们把整个Grid分成了三行和三列,第0行第一列来来呈现我们每一个TreeViewItem的Header属性,我们让其居中显示,在第1行第一列我们来显示一条直线,这里我们也是用的Rectangle,当然使用Border和使用Path的效果其实是一样的,这个每个人习惯不同,最后面一行我们来显示ItemsPresenter,这个和上面一篇形式上是差不多的,我们就不详细介绍,这里需要重点注意的是下面的内容。

<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True" Margin="10"></StackPanel>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>

  即ItemsPresenter是放在一个容器中的,这个容器决定了里面的Item到底需要通过怎样的方式来呈现,这里我们是使用的是横向排列的StackPanel控件来作为父容器的,另外需要注意到这个常用的Trigger

  <Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="VerLn" Value="0"/>
<Setter Property="Height" TargetName="itemsBorder" Value="0"/>
</Trigger>

  这个在TreeView控件中是非常常用的,这里需要特别注意。

接下里我们再看看当前的TreeView的具体数据绑定和其它的数据逻辑。

<TreeView Name="trvMenu" HorizontalContentAlignment="Center" VerticalContentAlignment="Center">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type self:MyTreeViewItem}"
ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal" Margin="10">
<Ellipse x:Name="ellipse" Width="16" Height="16" Margin="2,0,2,0" Fill="Transparent">
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard AutoReverse="True" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse">
<EasingColorKeyFrame KeyTime="0:0:0.0" Value="Transparent"/>
<EasingColorKeyFrame KeyTime="0:0:0.5" Value="DarkGreen"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
<Image x:Name="image"
Source="/TestTreeView;component/Images/connect.png"
Margin="2,0,2,0"
Width="24"
Height="24"
Stretch="Fill">
</Image>
<TextBlock Text="{Binding TreeViewItemName}" VerticalAlignment="Center" FontSize="16" Foreground="White" Margin="2,0,2,0"/>
</StackPanel>
<HierarchicalDataTemplate.Triggers>
<DataTrigger Binding="{Binding NodeType}" Value="采集服务器">
<Setter Property="Source" TargetName="image" Value="/TestTreeView;component/Images/connect.png"></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding NodeType}" Value="控制服务器">
<Setter Property="Source" TargetName="image" Value="/TestTreeView;component/Images/medium_alarm_hit.png"></Setter>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>

  这里需要注意的是当前的TreeViewItem直接是作用在TreeView上的,如果TreeViewItem添加了x:Key属性,那么该如何引用该TreeViewItem样式呢?正确的方式是设置TreeView的ItemContainerStyle属性,这里需要注意,这篇文章就介绍到这里,如果能够与前面的一篇内容结合起来看,那么相信对TreeView控件会有更多的理解吧!

重写TreeView模板来实现数据分层展示(二)的更多相关文章

  1. 重写TreeView模板来实现数据分层展示(一)

    总想花些时间来好好总结一下TreeView这个WPF控件,今天来通过下面的这几个例子来好好总结一下这个控件,首先来看看一个常规的带虚线的TreeView控件吧,在介绍具体如何完成之前首先来看看最终实现 ...

  2. springboot 使用model重定向到html模板,对数据进行展示

    1:使用springboot, ,html使用thymeleaf,nekohtml模板 在build.gradle中添加依赖 buildscript { repositories { mavenCen ...

  3. GIS案例学习笔记-CAD数据分层导入现有模板实例教程

    GIS案例学习笔记-CAD数据分层导入现有模板实例教程 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 1. 原始数据: CAD数据 目标模板 2. 任务:分5个图层 ...

  4. 移动端基于HTML模板和JSON数据的JavaScript交互

    写本文之前,我正在做一个基于Tab页的订单中心: 每点击一个TAB标签,会请求对应状态的订单列表.之前的项目,我会在js里使用 +  连接符连接多个html内容: var html = ''; htm ...

  5. python操作三大主流数据库(14)python操作redis之新闻项目实战②新闻数据的展示及修改、删除操作

    python操作三大主流数据库(14)python操作redis之新闻项目实战②新闻数据的展示及修改.删除操作 项目目录: ├── flask_redis_news.py ├── forms.py ├ ...

  6. 学会这一招,小白也能使用数据可视化BI软件创建医院数据实时展示大屏

    灯果数据可视化BI软件是新一代人工智能数据可视化大屏软件,内置丰富的大屏模板,可视化编辑操作,无需任何经验就可以创建属于你自己的大屏.大家可以在他们的官网下载软件.   本文以医院数据实时展示大屏为例 ...

  7. 各种JS模板引擎对比数据(高性能JavaScript模板引擎)

    最近做了JS模板引擎测试,拿各个JS模板引擎在不同浏览器上去运行同一程序,下面是模板引擎测试数据:通过测试artTemplate.juicer与doT引擎模板整体性能要有绝对优势: js模板引擎 Ja ...

  8. Thymeleaf+SpringMVC,如何从模板中获取数据

    Thymeleaf+SpringMVC,如何从模板中获取数据 在一个典型的SpringMVC应用中,带@Controller注解的类负责准备数据模型Map的数据和选择一个视图进行渲染.这个模型Map对 ...

  9. 在GridControl表格控件中实现多层级主从表数据的展示

    在一些应用场景中,我们需要实现多层级的数据表格显示,如常规的二级主从表数据展示,甚至也有多个层级展示的需求,那么我们如何通过DevExpress的GridControl控表格件实现这种业务需求呢?本篇 ...

随机推荐

  1. [TJOI2017]DNA

    嘟嘟嘟 这题怎么想都想不出来,最后还是敲了暴力,喜提40分-- 正解竟然也是暴力-- 用\(s_0\)构造SAM,然后把\(s\)扔上去暴力dfs:记录一个修改次数tot,如果当前不匹配,就tot + ...

  2. 钉钉自定义机器人 发送文本 换行 \n无效果

    今天用php做钉钉自定义机器人 发送文本 换行 \n无效果,原来是我一直用单引号作为定义字符串,换成双引号就ok了.

  3. pytorch例子学习——TRANSFER LEARNING TUTORIAL

    参考:https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html 以下是两种主要的迁移学习场景 微调convnet : ...

  4. DNS原理-HTTP原理-TCP原理

    第一章:企业DNS原理 相信大家都知道windows和linux的hosts文件是:IP地址和域名的对应关系,我们一般访问网站的步骤: 打开网页-----输入网址-------查看本地的DNS库是否存 ...

  5. eclipse如何设置断点&断点处运行快捷键

    第一步: 设置断点:在该行最前面边框双击  或快捷键:Ctrl+Shift+B   第二步: Debug 运行启动   第三部: 运行到断点后: 使用快捷键F5,F6,F7单步执行. F5:Step ...

  6. CentOS 6.5下RPM方式(重新)安装MySQL 5.7.21从头到尾篇

    强烈推荐参阅这一篇教程  https://www.cnblogs.com/kevingrace/p/8340690.html 下面我写的仅供参考 今天把Mysql5.1升级到了5.7,浪费了一天为了避 ...

  7. 深入理解Redis Cluster

    Redis Cluster采用虚拟槽分区,所有的key根据哈希函数映射到0~16383槽内,计算公式: slot = CRC16(key) & 16383 每个节点负责维护一部分槽以及槽所映射 ...

  8. 朱晔的互联网架构实践心得S2E3:品味Kubernetes的设计理念

    Kubernetes(k8s)是一款开源的优秀的容器编排调度系统,其本身也是一款分布式应用程序.虽然本系列文章讨论的是互联网架构,但是k8s的一些设计理念非常值得深思和借鉴,本人并非运维专家,本文尝试 ...

  9. java.util.Stack类中 empty() 和 isEmpty() 方法的作用

    最近在学习算法和数据结构,用到Java里的Stack类,但程序运行结果一直和我预料的不一样,网上也没查清楚,最后查了API,才搞明白. java.util.Stack继承类 java.util.Vec ...

  10. linus 下redis守护进程启动

    修改配置文件 sudo vim /usr/src/redis/redis.conf // 具体的安装目录不一样,以安装的时候为准 # 将daemonize 改为yes daemonize yes 重新 ...