WPF 中 TreeListView 的使用
前段时间在项目开发中需要用 TreeListView 的功能,于是在网上狂搜一通,倒也找到了几个小例子,但还是满足不了我简单的要求,由于时间紧也只能折中凑合着用了。最近时间比较充裕,把其中的例子整理一下分享给大家。在文章最后部分还有一个没解决的问题,也希望得到牛人的指点,小弟不胜感激 O(∩_∩)O~
文章中使用的是msdn提供的示例,源代码下载 - TreeListView.zip。修改后的程序代码下载 - TreeListViewSample.zip,修改前后的程序界面如下:

修改前

修改后
1 绑定数据
在msdn示例中,数据是直接写在 xaml文件中进行绑定的,如下所示:
<l:TreeListView>
<l:TreeListViewItem>
<l:TreeListViewItem.Header>
<x:Type TypeName="DependencyObject" />
</l:TreeListViewItem.Header>
<l:TreeListViewItem>
<l:TreeListViewItem.Header>
<x:Type TypeName="Visual" />
</l:TreeListViewItem.Header>
......
<l:TreeListViewItem>
<l:TreeListViewItem.Header>
<x:Type TypeName="GridViewColumnCollection" />
</l:TreeListViewItem.Header>
</l:TreeListViewItem>
<l:TreeListViewItem>
<l:TreeListViewItem.Header>
<x:Type TypeName="GridViewColumnHeaderRole" />
</l:TreeListViewItem.Header>
</l:TreeListViewItem>
</l:TreeListView>
这种做法的弊端不用多说,在我们实际开发过程中是绝对不允许的,下面我把它改成了基于MVVM的数据绑定方式。首先用 NuGet插件管理引入 MvvmLight,然后在Model中添加Staff类,Staff类中定义了一些在界面上显示的属性,在 ViewModel中添加 MainViewModel类,用来生成一些绑定到界面的测试数据,并将 MainViewModel实例赋值给 MainWindow的 DataContext:
MainViewModel vm = new MainViewModel();
this.DataContext = vm;
数据源准备完毕,接着就是对界面显示的改动,将绑定列的集合GridViewColumnCollection 改为下面的代码:
<GridViewColumnCollection x:Key="gvColumns">
<GridViewColumn Header="姓名"
CellTemplate="{StaticResource CellTemplate_Name}" Width="" />
<GridViewColumn Header="年龄"
DisplayMemberBinding="{Binding Age}" Width="" />
<GridViewColumn Header="性别"
DisplayMemberBinding="{Binding Sex}" Width="" />
<GridViewColumn Header="职务"
DisplayMemberBinding="{Binding Duty}" Width="" />
</GridViewColumnCollection>
最后一步,也是最关键的一步是给 TreeListView绑定数据源:
<l:TreeListView Background="WhiteSmoke" BorderBrush="#FF32C1FF" ItemsSource="{Binding StaffList}">
<l:TreeListView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding StaffList}" />
</l:TreeListView.ItemTemplate>
</l:TreeListView>
完成以上步骤,运行程序即可看到如下界面,动态创建的数据已经绑定到 TreeListView:

2 添加滚动条
按说能够动态的显示数据,主要的功能就算完成了,但在实际开发中许多细节的方面的东西还是需要考虑地,于是,为了 TreeListView能够更好的在程序中使用,就需要考虑更多的细节。运行 msdn提供的示例会发现显示内容超出控件本身的范围时并没有滚动条出现,下面是 msdn 中 TreeListView的样式:
<Style TargetType="{x:Type l:TreeListView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type l:TreeListView}">
<Border Padding="{TemplateBinding Padding}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<DockPanel>
<GridViewHeaderRowPresenter Columns="{StaticResource gvColumns}"
DockPanel.Dock="Top"/>
<ItemsPresenter />
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
我们可以看到最外层是Border,其内部是DockPanel,Panel包含了 GridViewHeaderRowPresenter(头部)和 ItemsPresenter(内容)两部分。根本就没有发现 ScrollViewer的影子,不出现滚动条也不奇怪了,下面的代码给它添加上了ScrollViewer:
<Style TargetType="{x:Type l:TreeListView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type l:TreeListView}">
<Border Padding="{TemplateBinding Padding}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}">
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Disabled">
<DockPanel>
<GridViewHeaderRowPresenter Columns="{StaticResource gvColumns}"
DockPanel.Dock="Top"/>
<ScrollViewer HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<ItemsPresenter />
</ScrollViewer>
</DockPanel>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这里可能有人会有疑问为什么添加两个ScrollViewer,只用外层的 ScrollViewer 并把属性VerticalScrollBarVisibility 设置为Auto不行吗?这样做也是可行的,只是在垂直滚动时列表标题行也会跟随滚动条滚动,而不是固定在顶端。
3 选中、展开节点
利用第一部分数据绑定的方式也可以实现自动选中、展开节点,在 Staff类中添加如下属性:
private bool _IsSelected;
private bool _IsExpanded; /// <summary>
/// 是否选中
/// </summary>
public bool IsSelected
{
get { return _IsSelected; }
set
{
_IsSelected = value;
this.RaisePropertyChanged("IsSelected");
}
}
/// <summary>
/// 是否展开
/// </summary>
public bool IsExpanded
{
get { return _IsExpanded; }
set
{
_IsExpanded = value;
this.RaisePropertyChanged("IsExpanded");
}
}
然后在 TreeListViewItem样式中,添加如下代码即可实现此功能:
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
<Setter Property="IsExpanded" Value="{Binding IsExpanded}" />
4 鼠标滑过改变背景色
对于 TreeListViewItem,在 Template的 ControlTemplate.Triggers中添加如下代码,即可实现此功能:
<Trigger Property="IsMouseOver" Value="true" SourceName="innerBorder">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="#FFC66152" TargetName="innerBorder"/>
</Trigger>
5 交替行样式
前面几部分把修改的主要部分进行了介绍,文章最后当然是提出那个没有解决的问题。
当看到文章开始部分修改后的程序截图时,您可能已经有怪怪的感觉,怎么行的背景色是这么变化的,杂乱无章,让它交替改变背景色多好!( ⊙ o ⊙ )是的,我也是想做出那样的效果,只是没有能够找到解决的方法,在此恳请牛人指点一二,多谢!
WPF 中 TreeListView 的使用的更多相关文章
- 在WPF中使用依赖注入的方式创建视图
在WPF中使用依赖注入的方式创建视图 0x00 问题的产生 互联网时代桌面开发真是越来越少了,很多应用都转到了浏览器端和移动智能终端,相应的软件开发上的新技术应用到桌面开发的文章也很少.我之前主要做W ...
- MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息
MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二 ...
- MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信
MVVM模式解析和在WPF中的实现(五) View和ViewModel的通信 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 M ...
- MVVM设计模式和WPF中的实现(四)事件绑定
MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...
- MVVM模式解析和在WPF中的实现(三)命令绑定
MVVM模式解析和在WPF中的实现(三) 命令绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...
- MVVM模式和在WPF中的实现(二)数据绑定
MVVM模式解析和在WPF中的实现(二) 数据绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...
- MVVM模式和在WPF中的实现(一)MVVM模式简介
MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...
- 【WPF】 Timer与 dispatcherTimer 在wpf中你应该用哪个?
源:Roboby 1.timer或重复生成timer事件,dispatchertimer是集成到队列中的一个时钟.2.dispatchertimer更适合在wpf中访问UI线程上的元素 3.Dispa ...
- 在WPF中使用WinForm控件方法
1. 首先添加对如下两个dll文件的引用:WindowsFormsIntegration.dll,System.Windows.Forms.dll. 2. 在要使用WinForm控 ...
随机推荐
- akw、grep、sed常用命令
awk 求和 cat data|awk '{sum+=$1} END {print "Sum = ", sum}' 平均值 cat data|awk '{sum+=$1} END ...
- Hibernate的回调与拦截
在Hibernate中,有两种方式可以捕获实体对象的GRUD操作并执行相应的处理 Hibernate回调(org.hibernate.classic.Lifecycle接口): //Provides ...
- [改善Java代码]用枚举实现工厂方法模式更简洁
工厂方法模式(Factory Method Patter)是"创建对象的接口",让子类决定实例化哪一个类,并使一个类的实例化延迟到其子类.工厂方法模式在我们的开发工作中,经常会用到 ...
- The Signals Of Process Communication
在之前大概的概述了进程之间的通信,下面笔者具体述说一下进程通信中最古老的一种通信方式之一---信号(Signals ),信号是用户进程之间通信和同步的一种原始机制,操作系统通过信号来通知进程系统中发生 ...
- Socket编程初探
一.什么是Socket? 通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.在Internet上的主机一般运行了多个服务软件,同时提供几种服务.每种服务都打开一个S ...
- 新增html元素的使用
今天学习HTML5中新增元素的使用 (Ⅰ)新增主体结构元素 Section元素:用于对网站或应用程序中的内容进行分块. <section> <h1></h1> &l ...
- ASP.NET二级域名站点共享Session状态
我的前面一篇文章提到了如何在使用了ASP.NET form authentication的二级站点之间共享登陆状态, http://www.cnblogs.com/jzywh/archive/2007 ...
- Editplus中使用正则表达式压缩代码
快捷键ctrl+H打开查找与替换窗口,勾上使用正则表达式选项,查找项输入\t|^( )+,替换范围选当前文档,选择全部替换按钮,然后查找项在输入\n,再选择全部替换按钮. 大功告成!
- Dalvik字节码的类型,方法与字段表示方法
Dalvik字节码有着自己的类型,方法与字段表示方法,这些方法与Dalvik虚拟机指令集一起组成了一条条的Dalvik汇编代码. 1.类型 Dalvik字节码只有两种类型,基本类型与引用类型.Dalv ...
- JSP之Cookie
Cookie是小段的文本信息,在网络服务器上生成,并发送给浏览器,通过使用cookie可以标识用户身份,记录用户名和密码,跟踪重复等. 首先创建index.jsp: <%@page import ...