前段时间在项目开发中需要用 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 的使用的更多相关文章

  1. 在WPF中使用依赖注入的方式创建视图

    在WPF中使用依赖注入的方式创建视图 0x00 问题的产生 互联网时代桌面开发真是越来越少了,很多应用都转到了浏览器端和移动智能终端,相应的软件开发上的新技术应用到桌面开发的文章也很少.我之前主要做W ...

  2. MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息

    MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二 ...

  3. MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信

    MVVM模式解析和在WPF中的实现(五) View和ViewModel的通信 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 M ...

  4. MVVM设计模式和WPF中的实现(四)事件绑定

    MVVM设计模式和在WPF中的实现(四) 事件绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  5. MVVM模式解析和在WPF中的实现(三)命令绑定

    MVVM模式解析和在WPF中的实现(三) 命令绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  6. MVVM模式和在WPF中的实现(二)数据绑定

    MVVM模式解析和在WPF中的实现(二) 数据绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  7. MVVM模式和在WPF中的实现(一)MVVM模式简介

    MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...

  8. 【WPF】 Timer与 dispatcherTimer 在wpf中你应该用哪个?

    源:Roboby 1.timer或重复生成timer事件,dispatchertimer是集成到队列中的一个时钟.2.dispatchertimer更适合在wpf中访问UI线程上的元素 3.Dispa ...

  9. 在WPF中使用WinForm控件方法

    1.      首先添加对如下两个dll文件的引用:WindowsFormsIntegration.dll,System.Windows.Forms.dll. 2.      在要使用WinForm控 ...

随机推荐

  1. SSO 登录功能的实现

    一.引言 自己早晚都会碰到的问题. 当需要到分离多站点多应用的时候,都是希望用户只要在一个站点登录,其它所有的应用站点都是已登录的状态. 查了下新浪与淘宝的登录的资料,自己实现了一个并做下记录. 二. ...

  2. Java基础知识强化之网络编程笔记25:Android网络通信之 Future接口介绍(Java程序执行超时)

    1. Future接口简介 在Java中,如果需要设定代码执行的最长时间,即超时,可以用Java线程池ExecutorService类配合Future接口来实现. Future接口是Java标准API ...

  3. Linux下安装配置Node及memcached

    这篇主要是记录Linux下安装Node及memcached遇到的问题及安装配置过程,方便日后查阅 Node安装及配置 [root@hostname ~]tar zxvf node-v0.12.4.ta ...

  4. MySQL中的保留字

    本文转载自:http://www.cnblogs.com/lawdong/archive/2010/08/08/2357903.html ADD ALL ALTER ANALYZE AND AS AS ...

  5. 集群服务器Session同步

    事实上,网站总是有状态的.每一个登录信息.用户信息常常被存储在session内部.而当一个网站被部署在不止一台服务器的时候,就会遇到session同步的问题.事实上即使一个很小的网站,也要至少有两台服 ...

  6. linux nginx启动 重启 关闭命令

    启动操作 nginx -c /usr/local/nginx/conf/nginx.conf -c参数指定了要加载的nginx配置文件路径 停止操作停止操作是通过向nginx进程发送信号来进行的 步骤 ...

  7. fatal error LNK1168: cannot open Debug/opreat.exe for writing

    问题:LINK : fatal error LNK1168: cannot open Debug/opreat.exe for writing           Error executing li ...

  8. 如何将 Font Awesome 转成 PNG 图标 详细教程 含源代码

    最近因为项目上需要用到这个字体图标,但是它里面的许多也不能完全满足项目需要,因此就考虑将这个图标导出,然后自己再添加一些其他图标使用 搜索了些解决方案,如:http://www.oschina.net ...

  9. c# 中日期的使用

    上月第一天:DateTime.Parse(DateTime.Now.AddMonths(-1).ToString("yyyy-MM-01")) 上周星期天:DateTime.Par ...

  10. Appcn 移动开发 前台与服务器数据交互

    第一次写.嘿嘿. 言归正传,这几天开始学习移动开发,使用的是Appcan平台.Appcan平台采用HTML5+CSS3做开发 实现跨平台,正好可以满足我们的业务需求. Appacn和数据库进行交互的方 ...