WPF中TreeListView的使⽤
  前段时间在项⽬开发中需要⽤ TreeListView 的功能,于是在⽹上狂搜⼀通,倒也到了⼏个⼩例⼦,但还是满⾜不了我简单的要求,由于时间紧也只能折中凑合着⽤了。最近时间⽐较充裕,把其中的例⼦整理⼀下分享给⼤家。在⽂章最后部分还有⼀个没解决的问题,也希望得到⽜⼈的指点,⼩弟不胜感激 O(∩_∩)O~
  ⽂章中使⽤的是msdn提供的⽰例,源代码下载 - 。修改后的程序代码下载 - ,修改前后的程序界⾯如下:
修改前
修改后
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="100" />
<GridViewColumn Header="年龄"
DisplayMemberBinding="{Binding Age}" Width="80" />
<GridViewColumn Header="性别"
DisplayMemberBinding="{Binding Sex}" Width="80" />
<GridViewColumn Header="职务"
DisplayMemberBinding="{Binding Duty}" Width="100" />
</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;
gridview不显示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 ⊙ )是的,我也是想做出那样的效果,只是没有能够到解决的⽅法,在此恳请⽜⼈指点⼀⼆,多谢!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。