標籤檢視
TabView 控制項是一種顯示索引標籤組合以及其各自內容的方式。 TabView 控制件有助於顯示內容數頁(或檔),同時讓使用者重新排列、關閉或開啟新的索引標籤。
這是正確的控制項嗎?
一般而言,索引標籤式UI有兩種不同的樣式之一,其功能與外觀不同:
- 靜態索引標籤 是通常位於設定視窗中的索引標籤型態。 它們包含固定順序的數個頁面,這些頁面通常包含預先定義的內容。
- 文件索引標籤是可在瀏覽器 (例如 Microsoft Edge) 中找到的索引標籤。 使用者可以建立、移除和重新排列索引標籤;在視窗之間移動索引標籤;並變更索引標籤的內容。
根據預設,TabView 會設定為提供檔索引標籤。 我們建議在使用者能夠:
- 動態開啟、關閉或重新排列索引標籤。
- 直接將文件或網頁開啟至索引標籤。
- 在視窗之間拖放索引標籤。
TabView API 允許設定靜態索引標籤的控制件。 不過,若要遵循 Windows 設計指引,並且如果有多於一些的靜態導覽項目,請考慮使用 NavigationView 控制項。
結構
Tabbed UI 是使用 TabView 控件和一或多個 TabViewItem 控件所建立。 TabView 裝載 TabViewItem 的實例,代表單一索引標籤及其內容。
TabView 元件
下圖顯示 TabView 控件的 部分。 標籤帶 具有頁首和頁尾,但與文件不同,標籤帶的頁首和頁尾分別位於帶的最左邊和最右邊。
TabViewItem 元件
下圖顯示 TabViewItem 控件 的各個部分。 雖然內容會顯示在 TabView 控件內,但內容實際上是 TabViewItem 的一部分。
建議
索引標籤選取
大部分的使用者都有使用網頁瀏覽器就能簡單使用文件索引標籤的體驗。 當使用者在您的應用程式中使用文件索引標籤時,先前的體驗會讓他們對索引標籤的行為有所期待。
無論使用者如何與一組文件索引標籤互動,當中必然有使用中的索引標籤。如果使用者關閉所選索引標籤,或進入所選索引標籤的細部而前往其他視窗,其他索引標籤就會變成使用中的索引標籤。TabView 會嘗試自動選取下一個索引標籤。如果您有充分理由將應用程式設為容許未選取索引標籤的 TabView,則 TabView 的內容區域就會顯示空白。
鍵盤導覽
根據預設,TabView 支援許多常見的鍵盤瀏覽案例。 本節說明內建功能,並提供其他功能的建議,這些功能對某些應用程式可能有用。
索引標籤和游標索引鍵行為
當焦點移至 TabStrip 區域時,選取的 TabViewItem 會獲得焦點。 然後,使用者可以使用左箭頭鍵和右箭頭鍵將焦點(非選取範圍)移到標籤列中的其他標籤。 箭號焦點會受困於索引標籤帶和新增索引標籤 (+) 按鈕 (如果有的話) 內。 若要將焦點移出定位帶區域,使用者可以按 Tab 鍵,將焦點移至下一個可設定焦點的元素。
透過索引標籤 移動焦點
移動焦點
箭頭鍵不會迴圈焦點
選取索引標籤
當 TabViewItem 有焦點時,請按 Space 或 Enter 選取該 TabViewItem。
使用箭頭鍵移動焦點,然後按 空格鍵 以選取標籤。
選取相鄰索引標籤的捷徑
按 Ctrl+Tab,選取下一個 TabViewItem。 按 Ctrl+Shift+Tab 以選取上一個 TabViewItem。 針對這些目的,索引標籤列表會「循環」,因此當選取最後一個標籤時,再次選取將會導致第一個標籤被選中。
關閉索引標籤
按下 Ctrl + F4 來觸發 TabCloseRequested 事件。 處理事件並關閉索引標籤 (如果適用)。
提示
如需詳細資訊,請參閱本文稍後的 開發人員鍵盤指引。
建立索引標籤檢視
- 重要 API:TabView 類別、TabViewItem 類別
WinUI 3 畫廊 應用程式包含大部分 WinUI 3 控制項、功能和特性的互動式範例。 從 Microsoft Store 取得應用程式,或在 GitHub 取得原始程式碼
本節中的範例顯示各種設定 TabView 控件的方式。
標籤頁面項目
TabView 中的每個選項卡都會以 TabViewItem 控制項 來表示,其中包含在選項卡區域中顯示的選項卡,以及在選項卡下方顯示的內容。
設定標籤
針對每個 TabViewItem,您可以設定標頭和圖示,並指定使用者是否可以關閉索引標籤。
-
Header 屬性通常會設定為字串值,以提供索引卷標的描述性標籤。不過,
Header
屬性可以是任何物件。 您也可以使用 HeaderTemplate 屬性來指定 DataTemplate,以定義應該如何顯示系結標頭數據。 - 設定 IconSource 屬性來指定標籤圖示。
- 根據預設,索引標籤會顯示關閉按鈕。 您可以將 IsClosable 屬性設定為
false
,以確保使用者無法關閉索引標籤。
針對 TabView,您可以設定適用於所有索引標籤的數個選項。
- 根據預設,關閉按鈕 (X) 總是顯示在可關閉的索引標籤上。 您可以將 CloseButtonOverlayMode 屬性設定為
OnPointerOver
,以變更此行為。 在此情況下,如果選取的索引標籤是可關閉的,則選取的索引標籤一律會顯示關閉按鈕;但未選取的索引標籤,只有在索引標籤可關閉且使用者將指標懸停在上面時,才會顯示關閉按鈕。 - 您可以設定 TabWidthMode 屬性,以變更索引卷標的大小。 (
TabViewItem
上會忽略Width
屬性。)這些是 中的 TabViewWidthMode 列舉中的選項:-
Equal
- 每個索引標籤的寬度都相同。 這是預設值。 -
SizeToContent
- 每個索引標籤都會根據內容自動調整寬度。 -
Compact
- 未選擇的索引標籤會收合,只顯示其圖示。 選取的索引標籤會調整以顯示索引標籤的內容。
-
內容
所選索引標籤中顯示的元素將新增至 TabViewItem的 Content 屬性。 TabViewItem 是 ContentControl,因此您可以將任何類型的物件新增為內容。 您也可以將 DataTemplate 套用至 ContentTemplate 属性。 如需詳細資訊,請參閱 ContentControl 類別。
本文中的範例顯示將文字直接新增至 XAML 中 Content
元素的簡單案例。 不過,實際UI通常更為複雜。 將複雜UI新增為索引標籤內容的常見方法是將它封裝在 UserControl 或 Page中,並將它新增為 TabViewItem 的內容。 此範例假設您的應用程式具有名為 PictureSettingsControl
的 XAML UserControl。
<TabViewItem>
<TabViewItem.Content>
<local:PictureSettingsControl/>
</TabViewItem.Content>
</TabViewItem>
靜態索引標籤
這個範例顯示具有兩個 靜態索引標籤的簡單 TabView。 這兩個索引標籤項目都會在 XAML 中新增為 TabView 的內容。
若要將 TabView 設為靜態,請使用下列設定:
- 將 IsAddTabButtonVisible 屬性設定為
false
,以隱藏 新增分頁 按鈕,並防止觸發 AddTabButtonClick 事件。 - 將 CanReorderTabs 屬性設定為
false
,以防止使用者將索引卷標拖曳到不同的順序。 - 在每個 TabViewItem上,將 IsClosable 屬性設定為 false,以隱藏 索引標籤關閉 按鈕,以防使用者觸發 TabCloseRequested 事件。
<TabView VerticalAlignment="Stretch"
IsAddTabButtonVisible="False"
CanReorderTabs="False">
<TabViewItem Header="Picture" IsClosable="False">
<TabViewItem.IconSource>
<SymbolIconSource Symbol="Pictures"/>
</TabViewItem.IconSource>
<TabViewItem.Content>
<StackPanel Padding="12">
<TextBlock Text="Picture settings"
Style="{ThemeResource TitleTextBlockStyle}"/>
</StackPanel>
</TabViewItem.Content>
</TabViewItem>
<TabViewItem Header="Sound" IsClosable="False">
<TabViewItem.IconSource>
<SymbolIconSource Symbol="Audio"/>
</TabViewItem.IconSource>
<TabViewItem.Content>
<StackPanel Padding="12">
<TextBlock Text="Sound settings"
Style="{ThemeResource TitleTextBlockStyle}"/>
</StackPanel>
</TabViewItem.Content>
</TabViewItem>
</TabView>
文件標籤頁
預設情況下,TabView 會為 索引標籤設定。 使用者可以新增索引標籤、重新排列索引標籤,以及關閉索引標籤。 在此組態中,您必須處理 AddTabButtonClick 和 TabCloseRequested 事件,才能啟用此功能。
當索引標籤被新增至 TabView 時,最終可能會有太多索引標籤以至於無法全部顯示在標籤列中。 在此情況下,捲動邊界會出現,讓使用者向左和向右捲動標籤列以存取隱藏的索引標籤。
這個範例會建立簡單的 TabView 以及事件處理常式,以支援開啟和關閉索引標籤。
TabView_AddTabButtonClick
事件處理程式示範如何在程序代碼中新增 TabViewItem。
<TabView VerticalAlignment="Stretch"
AddTabButtonClick="TabView_AddTabButtonClick"
TabCloseRequested="TabView_TabCloseRequested">
<TabViewItem Header="Home" IsClosable="False">
<TabViewItem.IconSource>
<SymbolIconSource Symbol="Home" />
</TabViewItem.IconSource>
<TabViewItem.Content>
<StackPanel Padding="12">
<TextBlock Text="TabView content"
Style="{ThemeResource TitleTextBlockStyle}"/>
</StackPanel>
</TabViewItem.Content>
</TabViewItem>
</TabView>
// Add a new tab to the TabView.
private void TabView_AddTabButtonClick(TabView sender, object args)
{
var newTab = new TabViewItem();
newTab.Header = $"New Document {sender.TabItems.Count}";
newTab.IconSource = new SymbolIconSource() { Symbol = Symbol.Document };
newTab.Content = new TextBlock() { Text = $"Content for new tab {sender.TabItems.Count}.",
Padding = new Thickness(12) };
sender.TabItems.Add(newTab);
sender.SelectedItem = newTab;
}
// Remove the requested tab from the TabView.
private void TabView_TabCloseRequested(TabView sender,
TabViewTabCloseRequestedEventArgs args)
{
sender.TabItems.Remove(args.Tab);
}
當最後一個標籤頁關閉時關閉視窗
如果應用程式中的所有索引標籤都是可關閉的,並且當最後一個索引標籤關閉時應該關閉應用程式視窗,那麼您也應該在TabCloseRequested事件處理程式中關閉視窗。
首先,在 App.xaml.cs
檔案中,新增公用屬性,可讓您從裝載 TabView 的 Page
存取 Window
實例。
public partial class App : Application
{
// ... code removed.
public Window? Window => m_window; // Add this.
private Window? m_window;
}
然後,修改 TabCloseRequested 事件處理程式,在 TabView 的所有索引標籤都被移除時,呼叫 Window.Close。
// Remove the requested tab from the TabView.
// If all tabs have been removed, close the Window.
private void TabView_TabCloseRequested(TabView sender,
TabViewTabCloseRequestedEventArgs args)
{
sender.TabItems.Remove(args.Tab);
if (sender.TabItems.Count == 0)
{
var window = (Application.Current as App)?.Window as MainWindow;
window?.Close();
}
}
注意
此範例適用於具有單一視窗的應用程式(MainWindow
)。 如果您的應用程式有多個視窗,或已啟用索引標籤分離,則需要追蹤視窗,然後尋找正確的視窗並關閉。 如需此範例,請參閱下一節。
Tab 卸除
Tab 撕除 描述使用者將索引標籤從 TabView 的標籤列拖出,並將其移動到另一個 TabView 控制項時會發生什麼情況,通常是在新視窗中。
從 Windows App SDK 1.6 開始,TabView 具有 CanTearOutTabs 屬性,您可以設定為提供將索引卷標拖曳至新視窗的增強體驗。 當使用者將索引標籤拖出已啟用此選項的定位帶時,會在拖曳期間立即建立新的視窗,讓使用者將它拖曳到螢幕邊緣,以最大化或 將視窗貼齊 一個平滑動作。 此實作也不會使用拖放 API,因此不會受到這些 API 中任何限制的影響。
當您將 CanTearOutTabs 屬性設定為 true
時,它將會觸發 索引標籤卸除 事件,而不是觸發 拖放 事件。 要實作分頁分離,必須應對以下事件:
-
當標籤頁第一次被拖出標籤列時,這個事件就會發生。 要處理此項操作,以建立新的視窗和 TabView,索引標籤將會移至這個新的選項卡視圖中。
-
這個事件會在提供新的 Window 之後發生。 處理它,將已損毀的索引標籤從原始的 TabView 移至新視窗中的 TabView。
-
當被撕下的索引標籤被拖曳到現有的 TabView 上時,就會發生此事件。 在接收被拆分索引標籤的 TabView 中進行處理,以指示是否應該接受該索引標籤。
-
當撕出的標籤被拖曳到現有的 TabView 上,且
ExternalTornOutTabsDropping
事件顯示當下允許釋放時,會發生此事件。 在接收已被拖出的索引標籤的 TabView 中處理,以便從原始 TabView 中移除該索引標籤,並將它插入到接收 TabView 的指定索引位置。
啟用分頁撕下功能時,不會引發這些事件:TabDragStarting、TabStripDragOver、TabStripDrop、TabDragCompleted、TabDroppedOutside。
謹慎
以系統管理員身分執行的程序支援 Tab 卸除。
下列範例示範如何實作事件處理程序以支援 Tab 拆分。
設定 TabView
此 XAML 會將 CanTearOutTabs 屬性設定為 true
,並設定索引標籤拆分事件處理程式。
<TabView x:Name="tabView"
CanTearOutTabs="True"
TabTearOutWindowRequested="TabView_TabTearOutWindowRequested"
TabTearOutRequested="TabView_TabTearOutRequested"
ExternalTornOutTabsDropping="TabView_ExternalTornOutTabsDropping"
ExternalTornOutTabsDropped="TabView_ExternalTornOutTabsDropped">
<!-- TabView content -->
</TabView>
建立和追蹤新視窗
索引標籤卸除需要您在應用程式中建立和管理新的視窗。
提示
WinUI 資源庫應用程式包含 WindowHelper
類別,可讓您更輕鬆地管理應用程式中的視窗。 您可以從 GitHub 的 WinUI Gallery 儲存庫中複製它:WindowHelper.cs。 我們建議使用這個輔助類別來實作 Tab 分離。請參閱 GitHub 上的 TabViewWindowingSamplePage,以了解其使用方式。
在本文中,輔助方法從 WindowHelper.cs
複製,並在修改後內嵌顯示以提高可讀性。
在這裡,會在 App.xaml.cs
中建立追蹤所有使用中視窗的清單。
OnLaunched
方法會更新為在建立視窗後進行追蹤。 (如果您使用 WindowHelper
類別,則不需要此項目。)
static public List<Window> ActiveWindows = new List<Window>();
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
m_window = new MainWindow();
// Track this window.
ActiveWindows.Add(m_window);
m_window.Activate();
}
當索引標籤卸除開始時,會要求新的視窗。 在這裡,變數 tabTearOutWindow
會在建立新窗口之後提供存取權。
CreateWindow
和 TrackWindow
協助程式方法會建立新的視窗,並將其新增至使用中窗口追蹤清單。
建立新視窗之後,您必須建立新的Page,並將其設定為視窗的內容。 新的 Page 必須包含 TabView 控件,您將將 TabTearOutRequested
事件處理程式中損毀的索引標籤移至其中。
提示
在此範例中,我們會建立新的 MainPage
類別,因為它只包含空白的 TabView(XAML 中不會直接新增任何索引標籤)。 如果 MainPage
包含其他不應該出現在損毀視窗中的 UI 元素,您可以建立只包含您所需元素的個別頁面(包括至少包含 TabView),以及建立該頁面的實例。
最後,將新視窗的 AppWindow.Id 指派給 args.
NewWindowId 屬性。 這會用於 TabViewTabTearOutRequestedEventArgs.NewWindowId 屬性中,讓您可以從該事件處理程式存取視窗。
private Window? tabTearOutWindow = null;
private void TabView_TabTearOutWindowRequested(TabView sender, TabViewTabTearOutWindowRequestedEventArgs args)
{
tabTearOutWindow = CreateWindow();
tabTearOutWindow.Content = new MainPage();
// Optional window setup, such as setting the icon or
// extending content into the title bar happens here.
args.NewWindowId = tabTearOutWindow.AppWindow.Id;
}
private Window CreateWindow()
{
Window newWindow = new Window
{
SystemBackdrop = new MicaBackdrop()
};
newWindow.Title = "Torn Out Window";
TrackWindow(newWindow);
return newWindow;
}
private void TrackWindow(Window window)
{
window.Closed += (sender, args) => {
App.ActiveWindows.Remove(window);
};
App.ActiveWindows.Add(window);
}
當最後一個索引標籤被關閉時關閉視窗
如先前所述,當您關閉 TabView 中的最後一個索引標籤時,您可能會想關閉視窗。 如果您的應用程式有多個視窗,您必須在您的追蹤視窗清單中,找到並關閉正確的視窗。 此範例示範如何執行此動作。
// Remove the requested tab from the TabView.
// If all tabs have been removed, close the Window.
private void TabView_TabCloseRequested(TabView sender, TabViewTabCloseRequestedEventArgs args)
{
sender.TabItems.Remove(args.Tab);
if (sender.TabItems.Count == 0)
{
GetWindowForElement(this)?.Close();
}
}
public Window? GetWindowForElement(UIElement element)
{
if (element.XamlRoot != null)
{
foreach (Window window in App.ActiveWindows)
{
if (element.XamlRoot == window.Content.XamlRoot)
{
return window;
}
}
}
return null;
}
將索引標籤移至新視窗
提供新視窗之後,您必須從 sender
TabView 中移除拆下的索引標籤,並將它加入至新視窗中的 TabView。 在此範例中,public AddTabToTabs
輔助方法允許您從原始頁面實例中存取新 MainPage
實例的 TabView,以便將已撕下的索引標籤加入其中。
private void TabView_TabTearOutRequested(TabView sender, TabViewTabTearOutRequestedEventArgs args)
{
if (tabTearOutWindow?.Content is MainPage newPage
&& args.Tabs.FirstOrDefault() is TabViewItem tab)
{
sender.TabItems.Remove(tab);
newPage.AddTabToTabs(tab);
}
}
// This method provides access to the TabView from
// another page instance so you can add the torn-out tab.
public void AddTabToTabs(TabViewItem tab)
{
tabView.TabItems.Add(tab);
}
將撕裂的索引標籤拖曳到另一個 TabView
當索引標籤被拖出並放入新視窗時,如先前步驟所示,可能會發生以下兩種情況之一:
- 用戶可以拖放分頁,並保持在新視窗中。 分離程序在此結束,不會再引發任何事件。
- 用戶可以繼續將拆分出來的索引卷標拖曳回現有的 TabView 控制項。 在此情況下,程式會繼續進行,並引發數個更多事件,讓您從原始的 TabView 移除索引標籤,並將外部索引標籤插入現有的 TabView 中。
當索引標籤拖曳到現有的 TabView 上時,會觸發 ExternalTornOutTabsDropping 事件。 在事件處理程式中,您可以判斷是否允許將索引標籤插入此 TabView 中。 在大部分情況下,您只需要將 args.
AllowDrop 屬性設定為 true
。 不過,如果您需要在設定該屬性之前執行任何檢查,您可以在這裡執行此動作。 如果將 AllowDrop
設定為 false
,頁籤拖曳動作會繼續,而且不會觸發 ExternalTornOutTabsDropped 事件。
private void TabView_ExternalTornOutTabsDropping(TabView sender,
TabViewExternalTornOutTabsDroppingEventArgs args)
{
args.AllowDrop = true;
}
如果 AllowDrop
設定為 ExternalTornOutTabsDropping
事件處理程式中的 true
,則會立即引發 ExternalTornOutTabsDropped
事件。
注意
事件名稱中的 Dropped
並不直接對應於拖放 API 中 放置 動作的概念。 在這裡,使用者不需要放開標籤即可執行 拖放 動作。 事件在將索引標籤懸停於索引標籤帶上時觸發,並執行程式代碼,以便 將索引標籤 拖動到 TabView 中。
ExternalTornOutTabsDropped 事件處理程式遵循與 TabTearOutRequested 事件相同的模式,但相反:您需要將索引標籤從原始的 TabView 移除,然後將它插入至 TabView sender
。
sender
TabView 是索引標籤要插入到的控制項,因此我們使用 GetParentTabView
輔助方法來尋找原始的索引標籤。它會從被拔出的 TabViewItem 開始,並使用 VisualTreeHelper 遍歷可視化樹狀結構,以尋找該項目所屬的 TabView。 找到 TabView 之後,TabViewItem 會從其 TabItems 集合中移除,然後插入至 sender
TabView 的 TabItems
集合中,於 args.
DropIndex所指定的索引位置。
private void TabView_ExternalTornOutTabsDropped(TabView sender,
TabViewExternalTornOutTabsDroppedEventArgs args)
{
if (args.Tabs.FirstOrDefault() is TabViewItem tab)
{
GetParentTabView(tab)?.TabItems.Remove(tab);
sender.TabItems.Insert(args.DropIndex, tab);
}
}
// Starting with the TabViewItem, walk up the
// visual tree until you get to the TabView.
private TabView? GetParentTabView(TabViewItem tab)
{
DependencyObject current = tab;
while (current != null)
{
if (current is TabView tabView)
{
return tabView;
}
current = VisualTreeHelper.GetParent(current);
}
return null;
}
提示
如果您使用 Windows Community Toolkit,您可以在工具組的 DependencyObjectExtensions 中使用 FindAscendant
輔助方法,而非 GetParentTabView
。
在視窗標題列中顯示 TabView 索引標籤
您可以將標籤和視窗標題列合併在同一個區域,而不是讓標籤在視窗標題列下方單獨佔據一行。 這會節省內容的垂直空間,並讓您的應用程式具有現代化的風格。
由於使用者可以依標題列拖曳視窗來重新定位視窗,因此標題列不會完全填滿索引標籤是很重要的。 因此,在標題列中顯示索引標籤時,您必須指定要保留為可拖曳區域的標題欄部分。 如果您未指定可拖曳的區域,則會拖曳整個標題欄,這可防止您的索引卷標接收輸入事件。 如果您的 TabView 會顯示在視窗的標題列中,您應該一律在 TabView 中包含 TabStripFooter,並將它標示為可拖曳的區域。
如需詳細資訊,請參閱標題列自訂
標題列中
<TabView VerticalAlignment="Stretch">
<TabViewItem Header="Home" IsClosable="False">
<TabViewItem.IconSource>
<SymbolIconSource Symbol="Home" />
</TabViewItem.IconSource>
</TabViewItem>
<TabView.TabStripFooter>
<Grid x:Name="CustomDragRegion" Background="Transparent" />
</TabView.TabStripFooter>
</TabView>
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var currentWindow = (Application.Current as App)?.Window as MainWindow;
currentWindow.ExtendsContentIntoTitleBar = true;
currentWindow.SetTitleBar(CustomDragRegion);
CustomDragRegion.MinWidth = 188;
}
注意
如何取得視窗的參照(currentWindow
),可能會因在應用程式中追蹤視窗的方式而有所不同。 如需詳細資訊,請參閱 關閉最後一個索引卷標 關閉視窗,並 建立和追蹤本文中的新視窗。
適用於開發人員的鍵盤指引
提示
如需內建鍵盤支援的詳細資訊,請參閱本文稍早的 鍵盤流覽。
有些應用程式可能需要更進階的鍵盤控制項。 如果適用於您的應用程式,請考慮執行下列快速鍵。
警告
如果要將 TabView 新增至現有的應用程式,您可能已經建立對應至建議 TabView 鍵盤快速鍵之按鍵組合的鍵盤快速鍵。 在此情況下,您必須考慮是否要保留現有的快速鍵,或為使用者提供直覺的索引標籤體驗。
- Ctrl + T 應該開啟新的索引標籤。一般而言,這個索引標籤會填入預先定義的檔,或是以簡單的方式建立空白來選擇其內容。 如果使用者必須選擇新索引標籤的內容,請考慮將輸入焦點提供給內容選取控制項。
- Ctrl + W 應該關閉選取的索引標籤。請記住,TabView 會自動選取下一個索引標籤。
- Ctrl + Shift + T 應該開啟最近關閉的分頁(或更精確地開啟與最近關閉的分頁相同內容的新分頁)。 從最近關閉的索引標籤開始,並在後續每次叫用快速鍵時向後移動。 請注意,這需要維護一份最近關閉的索引標籤清單。
- Ctrl + 1 應該選取索引標籤清單中的第一個索引標籤。 同樣地,Ctrl + 2 應選取第二個索引標籤,Ctrl + 3 應選取第三個,一直到 Ctrl + 8。
- Ctrl + 9 應該選取索引標籤清單中的最後一個索引標籤,無論清單中的標籤數目為何。
- 如果索引標籤提供的不只是關閉命令 (例如複製或釘選索引標籤),請使用內容功能表來顯示可在索引標籤上執行的所有可用動作。
實作瀏覽器樣式的鍵盤輸入行為
這個範例會在 TabView 上執行數個上述建議。 具體而言,這個範例會實作 ctrl + T、Ctrl + W、Ctrl + 1-8,以及 Ctrl + 9。
<TabView>
<!-- ... some tabs ... -->
<TabView.KeyboardAccelerators>
<KeyboardAccelerator Key="T" Modifiers="Control"
Invoked="NewTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="W" Modifiers="Control"
Invoked="CloseSelectedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number1" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number2" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number3" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number4" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number5" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number6" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number7" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number8" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
<KeyboardAccelerator Key="Number9" Modifiers="Control"
Invoked="NavigateToNumberedTabKeyboardAccelerator_Invoked" />
</TabView.KeyboardAccelerators>
</TabView>
private void NewTabKeyboardAccelerator_Invoked(KeyboardAccelerator sender,
KeyboardAcceleratorInvokedEventArgs args)
{
// Create new tab.
TabView senderTabView = (TabView)args.Element;
if (senderTabView != null)
{
// (Click handler defined in previous example.)
TabView_AddTabButtonClick(senderTabView, new EventArgs());
}
args.Handled = true;
}
private void CloseSelectedTabKeyboardAccelerator_Invoked(KeyboardAccelerator sender,
KeyboardAcceleratorInvokedEventArgs args)
{
TabView tabView = (TabView)args.Element;
TabViewItem tab = (TabViewItem)tabView.SelectedItem;
// Only remove the selected tab if it can be closed.
if (tabView is not null &&
tab.IsClosable == true)
{
tabView.TabItems.Remove(tab);
}
args.Handled = true;
}
private void NavigateToNumberedTabKeyboardAccelerator_Invoked(KeyboardAccelerator sender,
KeyboardAcceleratorInvokedEventArgs args)
{
TabView tabView = (TabView)args.Element;
int tabToSelect = 0;
switch (sender.Key)
{
case Windows.System.VirtualKey.Number1:
tabToSelect = 0;
break;
case Windows.System.VirtualKey.Number2:
tabToSelect = 1;
break;
case Windows.System.VirtualKey.Number3:
tabToSelect = 2;
break;
case Windows.System.VirtualKey.Number4:
tabToSelect = 3;
break;
case Windows.System.VirtualKey.Number5:
tabToSelect = 4;
break;
case Windows.System.VirtualKey.Number6:
tabToSelect = 5;
break;
case Windows.System.VirtualKey.Number7:
tabToSelect = 6;
break;
case Windows.System.VirtualKey.Number8:
tabToSelect = 7;
break;
case Windows.System.VirtualKey.Number9:
// Select the last tab
tabToSelect = tabView.TabItems.Count - 1;
break;
}
// Only select the tab if it is in the list.
if (tabToSelect < tabView.TabItems.Count)
{
tabView.SelectedIndex = tabToSelect;
}
}
UWP 和 WinUI 2
重要
本文中的資訊和範例已針對使用 Windows App SDK 和 WinUI 3的應用程式優化,但通常適用於使用 WinUI 2的 UWP 應用程式。 如需平臺特定資訊和範例,請參閱 UWP API 參考。
本節包含您在 UWP 或 WinUI 2 應用程式中使用控件所需的資訊。
UWP 應用程式的 TabView 控制項包含在 WinUI 2 中。 如需詳細資訊,包括安裝指示,請參閱 WinUI 2。 此控件的 API 存在於 命名空間Microsoft.UI.Xaml.Controls Microsoft。
Tab 分離 API 未包含在 WinUI 2 版的 TabView 中。
- WinUI 2 API:TabView 類別、TabViewItem 類別
-
開啟 WinUI 2 畫廊應用程式,並查看 TabView 的功能。
WinUI 2 Gallery 應用程式包含大部分 WinUI 2 控制項、功能和特性操作的互動範例。 從
Microsoft Store 取得應用程式,或在 GitHub取得原始程式碼。
我們建議使用最新的 WinUI 2,以取得所有控件的最新樣式、範本和功能。 WinUI 2.2 或更新版本包含一個供此控制項使用的新範本,其採用了圓角設計。 如需詳細資訊,請參閱 圓角半徑。
若要搭配 WinUI 2 使用本文中的程式代碼,請使用 XAML 中的別名(我們使用 muxc
)來代表專案中所包含的 Windows UI 連結庫 API。 如需詳細資訊,請參閱 開始使用 WinUI 2。
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
<muxc:TabView />