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控 ...
随机推荐
- struts2.1笔记02:servlet简介
1. Servlet 是在服务器上运行的小程序.这个词是在 Java applet的环境中创造的,Java applet 是一种当作单独文件跟网页一起发送的小程序,它通常用于在客户端运行,结果 ...
- 如何使用数据卷在宿主机和docker容器之间共享文件
共享宿主机的目录给容器 docker run -i -t -v ~/download:/home/hello python3-env /bin/bash -v 表示创建一个数据卷并挂载到容器里 ~/ ...
- 5个让DBA爱上你的SQL技巧
我的一个同事Martin Masarik,SQLde的CEO,跟我谈起了他的一个DBA朋友,他管理着一个国际银行的Oracle数据库,数据规模约2TB.Martin Masarik曾问他:“什么样的S ...
- coherence初识
近期,发现在预发布环境上的项目有些冲突,本着治病救人的原则,不得已要一步步剖析,苦逼的就是我们可爱可敬的程序员. 先介绍下大体情况,应用项目都是velocity+spring+mybatis,没什么好 ...
- Asp_CRUD
Asp_增删改查.逻辑流程 启动服务器. 地址为127.0.0.1 端口为随机分配 2607 然后在浏览器中输入http://localhost:2670/CRUD_main.ashx 浏览器像服务器 ...
- Android平台使用SQLite数据库存储数据
创建一个DataBaseHelper的类,这个类是继承SQLiteOpenHelper类的,这个类中包含创建数据库.打开数据库.创建表.添加数据和查询数据的方法.代码如下: package com.e ...
- ios app名字的多语言支持
经测试,不同版本的xcode会有操作细节不同,本次环境xcode6.4 1)编辑Info.plist,添加一个新的属性Application has localized display name, 设 ...
- Messenger实现Android IPC
当Service不需要支持并发操作时Messenger会非常有用.Messenger类使用Handler执行每个传入的消息,所有客户端的调用都按顺序运行在同一个线程上,这和AIDL是有区别的,AIDL ...
- Xcode-GitHub第三方库管理工具--CocoaPods
一.概要 iOS开发时,项目中会引用许多第三方库,CocoaPods(https://github.com/CocoaPods/CocoaPods)可以用来方便的统一管理这些第三方库(从一个坑出来,又 ...
- (转)实战Memcached缓存系统(8)Memcached异步实时读写问题的解决方案SAC
在使用Memcached时,一般实时读写的场景并不多见.但多是Memcached写入后,在一定时间后才会有读操作.但是如果应用场景,是写入后瞬间即会有读操作呢?似乎没有什么特别之处,我们依然可以这样写 ...