扩展的 WPF TabControl
修改 WPF TabControl 以显示单行滚动的 TabItem

引言
我最近决定尝试修改内置的 WPF TabControl
,使其行为类似于 Internet Explorer 7 的工作方式。
我想要更改的主要区域是 TabItems
的排列方式,目前内置的 TabControl
会打包和堆叠项目,所以项目越多,标题所需的空间就越大,从而占用 TabItem
的实际内容空间。
在 Internet Explorer 7 中,标签保持在单行上,并且会滚动进出视图。 这就是我希望此控件的行为方式。
属性/事件
控件中添加了一些额外的属性(依赖属性)和事件。
AllowAddNew
- 将此属性设置为true
将允许最终用户通过button
向控件添加新的tabitems
。AllowDelete
- 将此属性设置为true
将允许最终用户通过单击所选tabitem
上的关闭button
从控件中删除tabitems
。
如果将上述属性设置为 true
,则有三个事件与这些属性一起使用。 它们是 TabItemAdded
、TabItemClosing
和 TabItemClosed
:所有这些都提供对要添加/删除的 TabItem
的引用,TabItemClosing
事件提供了一个在需要时取消关闭的位置。
AddNewTabToEnd
- 如果此属性为true
,则使用AddNew button
添加的tabitems
将添加到tabitems
行的末尾,否则新的tabitem
将插入到当前选择的tabitem
之后。SelectNewTabOnCreate
- 如果此属性为true
,则焦点将移动到新添加的tabitem
。
最后,有三个额外的 Brush
类型的属性,用于根据它们的状态为 tabitems
着色
TabItemNormalBackground
TabItemMouseOverBackground
TabItemSelectedBackground
如果您查看本文顶部的图片,它显示了 TabControl
的默认样式。 我故意使它非常基本。 通过仅使用额外的 Background
属性,您可以轻松更改 TabControl
的外观。 如图所示,通过添加一些 LinearGradientBrushes
,您可以获得类似于 Internet Explorer 7 的东西。

有四个属性在 tabitems
的排列中起着积极作用。 它们是
TabItemMinWidth
TabItemMaxWidth
TabItemMinHeight
TabItemMaxHeight
排列 TabItems
tabcontrol
以三种方式排列其 tabitems
。
如果 TabStripPlacement
属性设置为 Top
或 Bottom
,则以下描述相关。
- 如果
TabItems
的总宽度小于可用的可见空间,那么我们只是将它们一个接一个地排列,考虑到TabItemMaxWidth
和TabItemMinWidth
属性。 - 如果总宽度大于可见宽度,则计算所有
tabitems
所需的宽度,以便所有都可见。 如果此宽度大于TabItemMinWidth
属性,则我们使用此计算的宽度排列tabitems
。 - 一旦我们添加了太多的
tabitems
,它们的宽度将小于TabitemMinWidth
属性,那么将启用滚动。
负责排列 tabitems
的类是 VirtualizingTabPanel
。 顾名思义,此面板派生自 VirtualizingPanel 类,并实现了 IScrollInfo 接口。 我不会在此处描述 VirtualizingPanel
是什么,而是将您定向到 Dan Crevier 的这篇 博客文章,其中描述了它是什么以及如何实现一个。
Using the Code
要使用该控件,您需要添加对 Wpf.TabControl
程序集的引用,然后向窗口添加一个 xmlns
xmlns:r="clr-namespace:Wpf.Controls;assembly=Wpf.TabControl"
提供的演示显示了如何将控件添加到窗口并设置其属性。
历史
- 2007 年 10 月 13 日:初始上传
- 2009 年 3 月 9 日:实现了
ItemsSource
绑定和错误修复 - 2009 年 4 月 5 日:更新源代码