前段时间在项目开发中需要用 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. 使用JS制作一个鼠标可拖的DIV(一)——鼠标拖动

    使用 JS 来实现一个可拖动的DIV,主要是使用到以下几个事件: 1.鼠标按下:DIV元素的onmousedown. 2.鼠标按住拖动:document 的 onmousemove 元素. 3.鼠标放 ...

  2. 字体的大小(pt)和像素(px)如何转换?

    px:相对长度单位.像素(Pixel). pt:绝对长度单位.点(Point). 1in = 2.54cm = 25.4 mm = 72pt = 6pc 具体换算是: Points Pixels Em ...

  3. CSS code snip enjoy.

    <!-- information-total得是动态获取吧. --> <div class="information-mod"> <div class ...

  4. MySQL密码忘记之解决方法

    方法一: 通过修改配置文件来登录mysql,方法也不难. 操作步骤: 在安装目录下找到配置文件my.ini 2.在my.ini中找到 [mysqld]字段,在它底下加上skip-grant-table ...

  5. asp.net连接oracle无法进行中文字符查询的问题

    用 select * from nls_database_parameters where parameter = 'NLS_CHARACTERSET' 查询服务器字符集为 AL32UTF8 数据库连 ...

  6. poj 3544 Journey with Pigs

    Journey with Pigs Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3004   Accepted: 922 ...

  7. ASP.NET运行原理

    1,ASP.NET运行原理: 客户端向服务器发出请求 → 服务器处理请求→ 处理好的数据以报文发给浏览器 → 浏览器显示请求结果 2,Chrome浏览器,查看请求过程:F12打开浏览器的调试窗口: 3 ...

  8. Linux 命令 - killall: 通过进程名向进程发送信号

    命令格式 killall [-Z CONTEXT] [-u USER] [ -eIgiqrvw ] [ -SIGNAL ] NAME... killall -l, --list killall -V, ...

  9. C# 利用ffmpeg 对视频转换系类操作 (1) 基本分析

    最近公司做一个项目,开发一个视频站点.项目需求中有很多视频转换的需求,如:格式转换(flv,Mp4),视频水印,视频截图,视频合成,获取视频的基本信息(时间戳,视频大小等).经过网络的收集资料以及自己 ...

  10. MVC下用户登录状态校验的问题以及解决方案--------------Action全局过滤器的使用

    前言当我们访问某个网站的时候需要检测用户是否已经登录(通过Session是否为null),我们知道在WebForm中可以定义一个BasePage类让他继承System.Web.UI.Page,重写它的 ...