设为首页 收藏本站
查看: 1797|回复: 0

WPF TreeView Win8 样式

[复制链接]

尚未签到

发表于 2015-5-20 12:22:26 | 显示全部楼层 |阅读模式
  WPF 的 TreeView 控件自带的样式如图 1 的左边所示,节点前的箭头还不错,但是选中效果实在是不给力,如果想更加华丽的话,那么很有必要把 TreeView 的样式好好自定义一番。我最后得到的结果如图 1 的右边所示,是一个 Win8 风格的 TreeView。
DSC0000.png
图 1 TreeView 样式对比
  在 WPF 中,自定义控件的外观是一件非常简单的事情,但对于 TreeView 来说,最大的困难则在于如何做到节点的整行选择。这是因为 TreeView 的项模板默认是如图 2 所示的。
DSC0001.png
图 2 TreeView 默认的项模板
  最外层是一个三列两行的 Grid,其中第一列用于放置 Expander(节点前的箭头),剩下的列则放置 PART_Header(标头内容)和子节点列表。因为子节点列表前空出了 Expander 那一列,所以 TreeView 的每层自然就有了缩进,同时也导致绘制边框时,无法令边框填满整行——因为不知道当前节点之前有多少层缩进。虽然也有取巧的办法,例如在绘制边框时,令 Margin.Left 足够小,但这仅适用于无边框背景,在定义 Win8 样式时不可用。
  所以需要有一种办法来计算出当前节点所在的层次(即深度)才可以。这里提供了一个好办法,即通过在可视化树中沿着 TreeViewItem 的父对象向上遍历,从而得到 TreeViewItem 所在的深度,代码如下所示:



public static int GetDepth(this TreeViewItem item) {
int depth = 0;
while ((item = item.GetAncestor()) != null) {
depth++;
}
return depth;
}
public static T GetAncestor(this DependencyObject source)
where T : DependencyObject {
do {
source = VisualTreeHelper.GetParent(source);
} while (source != null && !(source is T));
return source as T;
}

  这里需要使用 VisualTreeHelper.GetParent 方法来得到父对象,直接用 item.Parent 得到的会是 null。
  得到了深度,接下来就将 TreeViewItem 的模板重新定义一下,如图 3 所示。
DSC0002.png
图 3 自定义的 TreeView 项模板
  在自定义的模板中,所有节点都是使用 StackPanel 层叠排列的,所以此时是没有层次关系的,Border 是可以整行显示的。层次关系则是通过为 Grid 指定不同的 Margin.Left 来实现的,这就需要根据当前节点的深度,计算出需要缩进的距离。计算过程是利用 IValueConverter 来完成的:











public sealed class IndentConverter : IValueConverter {
public double Indent { get; set; }
public double MarginLeft { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
TreeViewItem item = value as TreeViewItem;
if (item == null) {
return new Thickness(0);
}
return new Thickness(this.MarginLeft + this.Indent * item.GetDepth(), 0, 0, 0);
}
}

  这里的缩进转换器,我定义了两个属性:Indent 和 MarginLeft,这是因为我将缩进距离由 19 调整到了 12,这样会使树更好看点,但会导致根节点距离左边框过近,所以就加入了 MarginLeft,使得根节点离左边框更远些,如图 4 所示。
DSC0003.png
图 4 缩进距离对比
  最后,就是样式的调整了。Win8 中的资源管理器树状列表的样式如图 5 所示,这个样式与 Win7 差不多,但是没有了渐变和圆角,实现起来要容易一些。需要注意的是被选中的节点,在鼠标经过的时候是会改变颜色的(虽然不是很明显),而且箭头无论是展开还是收起状态,在鼠标经过的时候都会变成蓝色。样式的定义没有什么好说的,一些颜色也在下图中标注出来了。
DSC0004.png
图 5 Win8 中的资源管理器
  Win8 资源管理器树状列表最华丽的一点是,当控件没有焦点且鼠标未经过的时候,所有箭头是隐藏的,有焦点的时候才出现,可惜这个不知道该怎么实现,只好先放下了。
  所有的样式定义我都放在了 \Resources\Win8Theme\TreeView.xaml 文件中,这是一个资源字典,只要在需要的地方使用  导入资源字典,TreeView 控件就可以以 Win8 样式显示。完整的代码和示例可以在这里下载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-68899-1-1.html 上篇帖子: #Win8# Secondary Tile 下篇帖子: 我看Win8 Metro C++
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表