Tabs
以 TabStrip 与 TabControl 形式提供默认、outline、pill、segmented 与 underline 五种外观的标签栏。
<TabControl Classes="underline" Width="320" HorizontalAlignment="Left">
<TabItem Header="Account">
<TextBlock Text="Make changes to your account here." Margin="0,12" />
</TabItem>
<TabItem Header="Profile">
<TextBlock Text="Edit your public profile." Margin="0,12" />
</TabItem>
<TabItem Header="Settings">
<TextBlock Text="Change your preferences." Margin="0,12" />
</TabItem>
</TabControl>用法
主题涵盖 TabStrip 与 TabStripItem(独立的标签栏),以及 TabControl 与 TabItem 的标签条(带内容的标签页)。外观是标签条或控件上的样式类:不加样式类即默认外观,也可以使用 outline、pill、segmented 或 underline。Pill、segmented 与 underline 以指示器呈现选中项,指示器沿 UIKit.Spring.Move 弹簧滑到选中的标签,并在选中项再次变化时中途反向;pill 的标签会随指示器滑动而淡入。尺寸:xsmall、small、large(不加则为 medium)。内容为图标的项请加 icon-only。标签只在键盘焦点时显示焦点环。借助 uikit:Tabs 附加属性,标签可以关闭、新增与拖拽(见关闭、添加与拖拽)。
示例
五种外观;最后一个 underline 标签处于禁用状态。
<StackPanel Spacing="16" HorizontalAlignment="Left">
<TabStrip Width="320" SelectedIndex="0">
<TabStripItem Content="Account" />
<TabStripItem Content="Profile" />
<TabStripItem Content="Settings" />
</TabStrip>
<TabStrip Classes="outline" Width="320" SelectedIndex="0">
<TabStripItem Content="Account" />
<TabStripItem Content="Profile" />
<TabStripItem Content="Settings" />
</TabStrip>
<TabStrip Classes="pill" Width="320" SelectedIndex="0">
<TabStripItem Content="Account" />
<TabStripItem Content="Profile" />
<TabStripItem Content="Settings" />
</TabStrip>
<TabStrip Classes="segmented" Width="320" SelectedIndex="0">
<TabStripItem Content="Account" />
<TabStripItem Content="Profile" />
<TabStripItem Content="Settings" />
</TabStrip>
<TabStrip Classes="underline" Width="320" SelectedIndex="0">
<TabStripItem Content="Account" />
<TabStripItem Content="Profile" />
<TabStripItem Content="Settings" IsEnabled="False" />
</TabStrip>
</StackPanel>pill 标签条的四种尺寸。
<StackPanel Spacing="16" HorizontalAlignment="Left">
<TabStrip Classes="pill xsmall" SelectedIndex="0">
<TabStripItem Content="Account" />
<TabStripItem Content="Profile" />
<TabStripItem Content="Settings" />
</TabStrip>
<TabStrip Classes="pill small" SelectedIndex="0">
<TabStripItem Content="Account" />
<TabStripItem Content="Profile" />
<TabStripItem Content="Settings" />
</TabStrip>
<TabStrip Classes="pill" SelectedIndex="0">
<TabStripItem Content="Account" />
<TabStripItem Content="Profile" />
<TabStripItem Content="Settings" />
</TabStrip>
<TabStrip Classes="pill large" SelectedIndex="0">
<TabStripItem Content="Account" />
<TabStripItem Content="Profile" />
<TabStripItem Content="Settings" />
</TabStrip>
</StackPanel>icon-only 项分别位于 pill 与 segmented 标签条中。
<StackPanel Spacing="16" HorizontalAlignment="Left">
<TabStrip Classes="pill" SelectedIndex="0">
<TabStripItem Classes="icon-only">
<PathIcon Data="{StaticResource UIKit.Icon.Inbox}" />
</TabStripItem>
<TabStripItem Classes="icon-only">
<PathIcon Data="{StaticResource UIKit.Icon.Star}" />
</TabStripItem>
<TabStripItem Classes="icon-only">
<PathIcon Data="{StaticResource UIKit.Icon.User}" />
</TabStripItem>
</TabStrip>
<TabStrip Classes="segmented" SelectedIndex="0">
<TabStripItem Classes="icon-only">
<PathIcon Data="{StaticResource UIKit.Icon.Inbox}" />
</TabStripItem>
<TabStripItem Classes="icon-only">
<PathIcon Data="{StaticResource UIKit.Icon.Star}" />
</TabStripItem>
<TabStripItem Classes="icon-only">
<PathIcon Data="{StaticResource UIKit.Icon.User}" />
</TabStripItem>
</TabStrip>
</StackPanel>菜单、前缀与后缀
放不下的标签会横向滚动,选中的标签会滚动到可见区域。menu 样式类在标签条末尾添加一个下拉按钮,列出所有标签,选中项打勾、禁用项为禁用状态,并选中点选的那一个。uikit:Tabs.Prefix 与 uikit:Tabs.Suffix 把内容放在标签条的起始与末尾,位于滚动区域之外;使用后缀或菜单时,标签末尾会留出 12px 间距。它们在 TabStrip 与 TabControl 上行为一致。
在 400px 宽的标签条中放六个标签,并带菜单、前缀与后缀。
<TabStrip Classes="menu" Width="400" VerticalAlignment="Top" SelectedIndex="0">
<uikit:Tabs.Prefix>
<StackPanel Orientation="Horizontal" Margin="4,0">
<Button Classes="ghost xsmall icon-only"><PathIcon Data="{StaticResource UIKit.Icon.ChevronLeft}" /></Button>
<Button Classes="ghost xsmall icon-only"><PathIcon Data="{StaticResource UIKit.Icon.ChevronRight}" /></Button>
</StackPanel>
</uikit:Tabs.Prefix>
<uikit:Tabs.Suffix>
<StackPanel Orientation="Horizontal" Margin="4,0">
<Button Classes="ghost xsmall icon-only"><PathIcon Data="{StaticResource UIKit.Icon.Inbox}" /></Button>
<Button Classes="ghost xsmall icon-only"><PathIcon Data="{StaticResource UIKit.Icon.Ellipsis}" /></Button>
</StackPanel>
</uikit:Tabs.Suffix>
<TabStripItem Content="Account" />
<TabStripItem Content="Profile" />
<TabStripItem Content="Settings" />
<TabStripItem Content="Billing" />
<TabStripItem Content="Notifications" IsEnabled="False" />
<TabStripItem Content="Integrations" />
</TabStrip>关闭、添加与拖拽
这些附加属性用于 TabStrip 或 TabControl。它们改变标签的来源列表:即 ItemsSource,必须是可变列表(例如 ObservableCollection),或者 Items。列表不可变的标签无法关闭或移动。
| 附加属性 | 作用 |
|---|---|
uikit:Tabs.Closable | 每个标签中显示关闭按钮,与 GPUI Kit 的可关闭标签一致:标签内边距为 px_2,末尾是一个 ghost xsmall 的 Close 按钮。在标签条上设置时作用于每个标签;在标签上设置时作用于该标签。 |
uikit:Tabs.NewTabFactory | 在最后一个标签之后显示添加按钮。它把函数返回的项添加到末尾并选中它。 |
uikit:Tabs.Reorderable | 标签可沿标签条拖拽以重新排序:被拖拽的标签跟随指针,其他标签让出位置,放下后移动其项。被拖拽的标签带有 :dragging 伪类,并绘制在途经的标签之上:有指示器时带指示器,outline 与 underline 中则使用活动标签的背景。标签溢出时,若把标签按住不放,标签条会滚动。 |
uikit:Tabs.DragGroup | 配合 Reorderable,把标签拖到同组的另一条标签条上即可移入其中。不同窗口中的标签条可以交换标签;在浏览器中,只有同一视图内的标签条可以。 |
uikit:Tabs.DetachedWindowFactory | 配合 DragGroup,把标签拖离本组的所有标签条后,它会移入函数返回的窗口,该窗口跟随指针直到放下。仅在窗口中可用。 |
关闭按钮在移除标签之前会在标签条上引发 uikit:Tabs.TabClosing;设置 Cancel 可保留标签。关闭选中的标签会选中下一个。
一个可关闭的标签条:添加按钮会新建标签,标签可重新排序。最后一个标签无法关闭。
<TabControl Name="Tabs" Width="480" HorizontalAlignment="Left"
uikit:Tabs.Closable="True" uikit:Tabs.Reorderable="True"
Loaded="OnLoaded">
<TabItem Header="Account">
<TextBlock Text="Make changes to your account here." Margin="0,12" />
</TabItem>
<TabItem Header="Profile">
<TextBlock Text="Edit your public profile." Margin="0,12" />
</TabItem>
<TabItem Header="Settings">
<TextBlock Text="Change your preferences." Margin="0,12" />
</TabItem>
</TabControl>Tabs.SetNewTabFactory(tabs, () => new TabItem { Header = $"Tab {++added}", Content = new TextBlock { Text = "A new tab." } });
Tabs.AddTabClosingHandler(tabs, (_, args) => args.Cancel = tabs.ItemCount == 1);通过拖拽重新排序标签。
<TabStrip Classes="pill" SelectedIndex="0" uikit:Tabs.Reorderable="True">
<TabStripItem Content="Account" />
<TabStripItem Content="Profile" />
<TabStripItem Content="Settings" />
<TabStripItem Content="Billing" />
<TabStripItem Content="Notifications" />
</TabStrip>同一组的两个标签条:把一个标签从一侧拖到另一侧。
<StackPanel Spacing="16" HorizontalAlignment="Left">
<TabStrip Width="360" SelectedIndex="0"
uikit:Tabs.Reorderable="True" uikit:Tabs.DragGroup="files">
<TabStripItem Content="index.html" />
<TabStripItem Content="style.css" />
<TabStripItem Content="app.js" />
</TabStrip>
<TabStrip Width="360" SelectedIndex="0"
uikit:Tabs.Reorderable="True" uikit:Tabs.DragGroup="files">
<TabStripItem Content="README.md" />
<TabStripItem Content="LICENSE" />
</TabStrip>
</StackPanel>把标签拖出为窗口
uikit:Tabs.DetachedWindowFactory 接收被拖出标签的项,并返回它要移入的窗口。该窗口必须包含同组的 TabStrip 或 TabControl,为空且可重新排序;标签会被放入其中,窗口在指针下方显示并跟随指针。拖到同组的标签条上时,标签移回,窗口隐藏。以此方式创建的窗口在其最后一个标签被拖出或关闭时关闭;拖动其唯一的标签则会移动窗口本身。应用自行打开的窗口在标签条清空后仍保持打开。
Tabs.SetDetachedWindowFactory(documents, _ => NewDocumentWindow());
static Window NewDocumentWindow()
{
var tabs = new TabControl();
Tabs.SetClosable(tabs, true);
Tabs.SetReorderable(tabs, true);
Tabs.SetDragGroup(tabs, "documents");
Tabs.SetDetachedWindowFactory(tabs, _ => NewDocumentWindow());
return new Window { Title = "Documents", Width = 640, Height = 400, Content = tabs };
}页面没有窗口,因此该示例不会在实时演示中运行。