博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WPF自适应可关闭的TabControl 类似浏览器的标签页
阅读量:6202 次
发布时间:2019-06-21

本文共 2059 字,大约阅读时间需要 6 分钟。

原文:

效果如图:

 

虽然说是自适应可关闭的TabControl,但TabControl并不需要改动,不如叫自适应可关闭的TabItem.

大体思路:建一个用户控件,继承自TabItem,里面放个按钮,点击的时候在TabControl中移除自身.在添加,移除TabItem和TabControl尺寸变化时,通过Items的个数计算合适的Width.

新建用户控件

新建用户控件,并继承自TabItem,这样它就拥有TabItem所有的属性和事件.而这个功能不需要自定义依赖属性和事件.它的用法就和TabItem完全一样.

建完后把UserControl换成TabItem,去掉多余部分

后台继承自UserControl改成继承自TabItem

更改样式添加关闭按钮

在Xmal里添加一个自己喜欢的样式,最主要的是在Template里添加一个按钮,注册一个Click事件,用于关闭.

1 
View Code

 

后台的逻辑

查找父级TabControl

注意TabItem并不能关闭自身,这里所说的关闭其实是在他父级TabControl的Items集合里移除.而且父级TabControl的尺寸改变时还要注册事件去改变每个Item的Width.所以我决定找到它的父级TabControl,声明一个私有变量添加对父级的引用.

可以通过可视化树的帮助类VisualTreeHelper来找到它的父级TabControl.当然并不是它的父级直接就是TabControl了,需要递归去查找

1 ///  2         /// 递归找父级TabControl 3         ///  4         /// 依赖对象 5         /// 
TabControl
6 private TabControl FindParentTabControl(DependencyObject reference) 7 { 8 DependencyObject dObj = VisualTreeHelper.GetParent(reference); 9 if (dObj == null)10 return null;11 if (dObj.GetType() == typeof(TabControl))12 return dObj as TabControl;13 else14 return FindParentTabControl(dObj);15 }
View Code

 

计算尺寸

既然是自适应,总得有一个正常的尺寸,只有空间不足的时候才去缩小每个Item.我想到的最简单的办法就是做个约定,把这个尺寸放到父级TabControl的Tag里,这样可以通过对父级TabControl的引用,轻松拿到这个尺寸.

计算方法就是取父级TabControl运行时的宽度ActualWidth除以约定的尺寸,取整形int,这个就是保持约定宽度item个数的临界值了.

小于等于这个值就用约定宽度,大于这个值就用父级运行宽度除以Items的个数求出平均宽度,然后遍历父级TabControl的Items,都赋上这个平均值.

需要注意的是,如果所有Items的尺寸加起来大于等于父级的尺寸,Items会换行,感觉有点丑啊.所以我取的是父级运行宽度-5做的运算,这样就永远也抵达不到边界,不会换行.

不过也可以改写TabControl的控件模版,把放Hrader的容器换成Stackpanel就不会换行了,我只是觉得上面的方法比较简单.

父级尺寸改变

可以通过TabControl的SizeChanged事件监测到.需要干的事就是重新计算尺寸.

关闭按钮

在父级TabControl的Items集合里移除自身后,注意重新计算下尺寸和移除注册SizeChanged事件的方法.

最后附上代码

这个效果比较常见,可能您已经做过了,有更好的想法希望您能分享出来,大家共同进步.

 

2016-08-16更新:感谢园友  的反馈,源码已改正

1.TabItem.Resources的关闭按钮样式添加了Key,模版里的关闭按钮添加了对资源的引用.

2.去掉了TabItem样式的HorizontalContentAlignment="Left",VerticalContentAlignment="Center".头部内容的布局方式改为HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}".

转载地址:http://fcxca.baihongyu.com/

你可能感兴趣的文章
递推3--位数问题
查看>>
《自控力》笔记
查看>>
redis主从配置及主从切换
查看>>
HackingTeam重磅炸弹: 估值超1000万美金带有军火交易性质的木马病毒以及远控源代码泄露...
查看>>
Flask的集中控制
查看>>
浅谈外连接中的on条件字句
查看>>
Google面试题-高楼扔鸡蛋问题
查看>>
Marching squares & Marching cubes
查看>>
关于在真实物理机器上用cloudermanger或ambari搭建大数据集群注意事项总结、经验和感悟心得(图文详解)...
查看>>
Android设置系统开机自己主动永不休眠
查看>>
MediaPlayer 状态机 API 详解 示例
查看>>
ECharts实例开发学习笔记二——时间轴
查看>>
C++再论单例模式
查看>>
C# 异步上传图片案例
查看>>
eclipse安装使用jetty
查看>>
eclipse中git的使用
查看>>
Linux日期时间显示输出
查看>>
JSON 数据格式
查看>>
python--批量下载豆瓣图片之升级版本
查看>>
到底怎么理解这个复数和复指数??
查看>>