WPF TreeView Win8 样式WPF 的 TreeView 控件自带的样式如图 1 的左边所示,节点前的箭头还不错,但是选中效果实在是不给力,如果想更加华丽的话,那么很有必要把 TreeView 的样式好好自定义一番。我最后得到的结果如图 1 的右边所示,是一个 Win8 风格的 TreeView。 图 1 TreeView 样式对比 在 WPF 中,自定义控件的外观是一件非常简单的事情,但对于 TreeView 来说,最大的困难则在于如何做到节点的整行选择。这是因为 TreeView 的项模板默认是如图 2 所示的。 图 2 TreeView 默认的项模板 最外层是一个三列两行的 Grid,其中第一列用于放置 Expander(节点前的箭头),剩下的列则放置 PART_Header(标头内容)和子节点列表。因为子节点列表前空出了 Expander 那一列,所以 TreeView 的每层自然就有了缩进,同时也导致绘制边框时,无法令边框填满整行——因为不知道当前节点之前有多少层缩进。虽然也有取巧的办法,例如在绘制边框时,令 Margin.Left 足够小,但这仅适用于无边框背景,在定义 Win8 样式时不可用。 所以需要有一种办法来计算出当前节点所在的层次(即深度)才可以。这里提供了一个好办法,即通过在可视化树中沿着 TreeViewItem 的父对象向上遍历,从而得到 TreeViewItem 所在的深度,代码如下所示:
这里需要使用 VisualTreeHelper.GetParent 方法来得到父对象,直接用 item.Parent 得到的会是 null。 得到了深度,接下来就将 TreeViewItem 的模板重新定义一下,如图 3 所示。 图 3 自定义的 TreeView 项模板 在自定义的模板中,所有节点都是使用 StackPanel 层叠排列的,所以此时是没有层次关系的,Border 是可以整行显示的。层次关系则是通过为 Grid 指定不同的 Margin.Left 来实现的,这就需要根据当前节点的深度,计算出需要缩进的距离。计算过程是利用 IValueConverter 来完成的:
这里的缩进转换器,我定义了两个属性:Indent 和 MarginLeft,这是因为我将缩进距离由 19 调整到了 12,这样会使树更好看点,但会导致根节点距离左边框过近,所以就加入了 MarginLeft,使得根节点离左边框更远些,如图 4 所示。 图 4 缩进距离对比 最后,就是样式的调整了。Win8 中的资源管理器树状列表的样式如图 5 所示,这个样式与 Win7 差不多,但是没有了渐变和圆角,实现起来要容易一些。需要注意的是被选中的节点,在鼠标经过的时候是会改变颜色的(虽然不是很明显),而且箭头无论是展开还是收起状态,在鼠标经过的时候都会变成蓝色。样式的定义没有什么好说的,一些颜色也在下图中标注出来了。 图 5 Win8 中的资源管理器 Win8 资源管理器树状列表最华丽的一点是,当控件没有焦点且鼠标未经过的时候,所有箭头是隐藏的,有焦点的时候才出现,可惜这个不知道该怎么实现,只好先放下了。 所有的样式定义我都放在了 \Resources\Win8Theme\TreeView.xaml 文件中,这是一个资源字典,只要在需要的地方使用 <ResourceDictionary Source="Resources/Win8Theme/TreeView.xaml" /> 导入资源字典,TreeView 控件就可以以 Win8 样式显示。完整的代码和示例可以在这里下载。
作者:CYJB
|
|
来自: 牛人的尾巴 > 《treeview控件》