wpf中TabControl的TabItem如何平分宽度,让他平均分布在整个面板中
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了wpf中TabControl的TabItem如何平分宽度,让他平均分布在整个面板中相关的知识,希望对你有一定的参考价值。
参考技术A 1、做法1,重写TabItem的Style,将Width设为一致,前提是这个Width要能兜得住一般的大小。2、做法2,重写TabControl的Style,将它的Panel换成UniformGrid,并设置Rows=1追问
已经重写无法平均分配宽度,只能定死,但有不能定死,希望它根据我最外层的宽来平均分配
追答你用做法2就可以了,TabControl的Style里面有个叫HeaderPanel的部件,类型是TabPanel,你把它换成UniformGrid,设置Rows=1,以及IsItemsHost=True即可
追问您能把您的联系方式给我吗,我是初学者,实在是太难了,能指导一下吗
追答这是基础,不是难。当然,难的东西学会了才有价值么不是?
打开Blend一步步来吧
1、进入修改TabControl样式编辑状态:
2、注意看模版有一个HeaderPanel,类型是TabPanel,这个就是要修改的目标
注意看它这几个属性,稍后UniformGrid也要做类似修改
3、添加UniformGrid,先到所有控件中搜索
然后添加到根容器下面
接着修改它的属性,跟HeaderPanel类似,额外的是需要设置Rows=1
4、把原来的HeaderPanel删掉,把新加的UniformGrid名字改为HeaderPanel(主要是一些触发器要用,触发器逻辑自己修改,不赘述)
5、现在已经看到修改后的效果了
WPF自适应可关闭的TabControl 类似浏览器的标签页(转)
效果如图:
虽然说是自适应可关闭的TabControl,但TabControl并不需要改动,不如叫自适应可关闭的TabItem.
大体思路:建一个用户控件,继承自TabItem,里面放个按钮,点击的时候在TabControl中移除自身.在添加,移除TabItem和TabControl尺寸变化时,通过Items的个数计算合适的Width.
新建用户控件
新建用户控件,并继承自TabItem,这样它就拥有TabItem所有的属性和事件.而这个功能不需要自定义依赖属性和事件.它的用法就和TabItem完全一样.
建完后把UserControl换成TabItem,去掉多余部分
后台继承自UserControl改成继承自TabItem
更改样式添加关闭按钮
在Xmal里添加一个自己喜欢的样式,最主要的是在Template里添加一个按钮,注册一个Click事件,用于关闭.
1 <Style TargetType="{x:Type TabItem}"> 2 <Setter Property="BorderBrush" Value="Black"></Setter> 3 <Setter Property="Background" Value="White"></Setter> 4 <Setter Property="Foreground" Value="Black"></Setter> 5 <Setter Property="Padding" Value="5,0,0,0"></Setter> 6 <Setter Property="HorizontalAlignment" Value="Left"></Setter> 7 <Setter Property="VerticalAlignment" Value="Center"></Setter> 8 <Setter Property="HorizontalContentAlignment" Value="Left"></Setter> 9 <Setter Property="VerticalContentAlignment" Value="Center"></Setter> 10 <Setter Property="Template"> 11 <Setter.Value> 12 <ControlTemplate TargetType="{x:Type TabItem}"> 13 <Border CornerRadius="5,0,0,0" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"> 14 <Grid> 15 <Grid.ColumnDefinitions> 16 <ColumnDefinition Width="*"></ColumnDefinition> 17 <ColumnDefinition Width="20"></ColumnDefinition> 18 </Grid.ColumnDefinitions> 19 <ContentPresenter Grid.Column="0" ContentSource="Header" Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"></ContentPresenter> 20 <Button Grid.Column="1" Name="btn_Close" Click="btn_Close_Click"></Button> 21 </Grid> 22 </Border> 23 <ControlTemplate.Triggers> 24 <Trigger Property="IsSelected" Value="true"> 25 <Setter Property="Background" Value="#FFFF923E"></Setter> 26 <Setter Property="Foreground" Value="White"></Setter> 27 </Trigger> 28 </ControlTemplate.Triggers> 29 </ControlTemplate> 30 </Setter.Value> 31 </Setter> 32 </Style>
后台的逻辑
查找父级TabControl
注意TabItem并不能关闭自身,这里所说的关闭其实是在他父级TabControl的Items集合里移除.而且父级TabControl的尺寸改变时还要注册事件去改变每个Item的Width.所以我决定找到它的父级TabControl,声明一个私有变量添加对父级的引用.
可以通过可视化树的帮助类VisualTreeHelper来找到它的父级TabControl.当然并不是它的父级直接就是TabControl了,需要递归去查找
1 /// <summary> 2 /// 递归找父级TabControl 3 /// </summary> 4 /// <param name="reference">依赖对象</param> 5 /// <returns>TabControl</returns> 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 else 14 return FindParentTabControl(dObj); 15 }
计算尺寸
既然是自适应,总得有一个正常的尺寸,只有空间不足的时候才去缩小每个Item.我想到的最简单的办法就是做个约定,把这个尺寸放到父级TabControl的Tag里,这样可以通过对父级TabControl的引用,轻松拿到这个尺寸.
计算方法就是取父级TabControl运行时的宽度ActualWidth除以约定的尺寸,取整形int,这个就是保持约定宽度item个数的临界值了.
小于等于这个值就用约定宽度,大于这个值就用父级运行宽度除以Items的个数求出平均宽度,然后遍历父级TabControl的Items,都赋上这个平均值.
需要注意的是,如果所有Items的尺寸加起来大于等于父级的尺寸,Items会换行,感觉有点丑啊.所以我取的是父级运行宽度-5做的运算,这样就永远也抵达不到边界,不会换行.
不过也可以改写TabControl的控件模版,把放Hrader的容器换成Stackpanel就不会换行了,我只是觉得上面的方法比较简单.
父级尺寸改变
可以通过TabControl的SizeChanged事件监测到.需要干的事就是重新计算尺寸.
关闭按钮
在父级TabControl的Items集合里移除自身后,注意重新计算下尺寸和移除注册SizeChanged事件的方法.
最后附上代码 自适应可关闭的Tab
这个效果比较常见,可能您已经做过了,有更好的想法希望您能分享出来,大家共同进步
以上是关于wpf中TabControl的TabItem如何平分宽度,让他平均分布在整个面板中的主要内容,如果未能解决你的问题,请参考以下文章
放置在 tabcontrol 的第二个 tabitem 中的数据网格的 WPF-'Index out of Range' 错误(但如果放置在第一个 tabitem 中,它工作正常)
如何将自定义控件派生的 TabItem 添加到 WPF 中的 TabControl?
WPF Adorner 在TabControl切换TabItem时消失