前段时间在项目开发中需要用 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. html笔记02:html,body { ……}

    html,body { margin:0px; height:100%; } html元素可告知浏览器其自身是一个 HTML 文档.body 元素定义文档的主体.它包含文档的所有内容(比如文本.图像. ...

  2. oracle索引、 管理权限和角色

    索引 1 单列索引create index 索引名 on 表名(列名): 2复合索引在同一张表上可以有多个索引,但是要求列的组合必须不同.create index 索引名 on 表名(列名1, 列名2 ...

  3. iOS 新特性关键字

    1.用来修饰属性,或者方法的参数,方法的返回值 /** nullable:表示可以传空 */ //@property (nonatomic, strong, nullable) NSString *n ...

  4. js常用代码收藏

    --1.遍历string分割为数组 <script language="javascript"> str="2,2,3,5,6,6"; //这是一字 ...

  5. Adobe Edge Animate –使用EdgeCommons加载和播放音频

    Adobe Edge Animate –使用EdgeCommons加载和播放音频 版权声明: 本文版权属于 北京联友天下科技发展有限公司. 转载的时候请注明版权和原文地址. 在Edge中,可以new一 ...

  6. Wince 对话框程序设计

    如何编程实现wince下“打开文件夹对话框”呢?这里就要涉及到下面要分析的知识了,对话框是一种特殊的窗口,它在wince 作为应用程序和程序使用者之间的交流窗口,通过显示和获取信息使人们的交流更加方便 ...

  7. hdu 4251 划分树

    思路:裸的划分树 #include<iostream> #include<algorithm> #include<cstdio> #include<cmath ...

  8. hdu 4374 单调队列优化动态规划

    思路:我只想说,while(head<=rear&&que[rear].val+sum[j]-sum[que[rear].pos-1]<=dp[i-1][j]+num[i- ...

  9. asp.net mvc 的几种分页Pager

    第一种 /// <summary> /// 分页Pager显示 /// </summary> /// <param name="html">&l ...

  10. Redis 命令 - Sorted Sets

    ZADD key score member [score member ...] Add one or more members to a sorted set, or update its scor ...