TabView コントロールは、一連のタブとそれぞれの内容を表示するための手段です。 TabView コントロールは、ユーザーが新しいタブを並べ替えたり、閉じたり、開いたりしながら、コンテンツの複数のページ (またはドキュメント) を表示する場合に便利です。
これは適切なコントロールですか?
一般に、タブ付き UI には、関数と外観が異なる 2 つの異なるスタイルのいずれかが含まれます。
- 静的タブ は、設定ウィンドウでよく見られるタブの一種です。 通常、内容があらかじめ定義されている固定順序の複数のページが含まれます。
- ドキュメント タブ は、Microsoft Edge などのブラウザーで使用されるタブの一種です。 ユーザーは、タブの作成、削除、再配置、ウィンドウ間でのタブの移動、タブの内容の変更を行うことができます。
既定では、 TabView はドキュメント タブを提供するように構成されています。 ユーザーが次のことを実行できる場合は、TabView をお勧めします。
- タブを動的に開く、閉じる、または並べ替える。
- ドキュメントまたは Web ページをタブに直接開きます。
- ウィンドウ間でタブをドラッグ アンド ドロップします。
TabView API では、静的タブのコントロールを構成できます。 ただし、Windows の設計ガイダンスに従い、静的なナビゲーション項目が複数ある場合は、 NavigationView コントロールの使用を検討してください。
構造
タブ付き UI は、TabView コントロールと 1 つ以上の TabViewItem コントロールを使用して作成されます。 TabView は、1 つのタブとそのコンテンツを表す TabViewItem のインスタンスをホストします。
TabView パーツ
この図は 、TabView コントロールの部分を示しています。 タブ ストリップにはヘッダーとフッターがありますが、ドキュメントとは異なり、タブ ストリップのヘッダーとフッターはそれぞれストリップの左端と右端にあります。
TabViewItem パーツ
この図は 、TabViewItem コントロールの部分を示しています。 コンテンツは TabView コントロール内に表示されますが、コンテンツは実際には TabViewItem の一部です。
推奨 事項
タブの選択
ほとんどのユーザーは、Web ブラウザーを使用して簡単にドキュメント タブを使用した経験があります。 アプリでドキュメント タブを使用するとき、ユーザーは経験からタブがどのように動作するかを予期します。
ユーザーが一連のドキュメント タブを操作する方法に関係なく、常にアクティブなタブが存在する必要があります。ユーザーが選択したタブを閉じたり、選択したタブを別のウィンドウに分割したりすると、別のタブがアクティブなタブになります。 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 プロパティを設定して、タブのアイコンを指定します。
- 既定では、タブには 閉じるボタン (X) が表示されます。 IsClosable プロパティを
false
に設定すると、閉じるボタンを非表示にし、ユーザーがタブを閉じることができないことを確認できます (閉じる要求されたイベントの外部でアプリ コードのタブを閉じる場合は、最初にIsClosable
がtrue
されていることを確認する必要があります)。
TabView では、すべてのタブに適用される複数のオプションを構成できます。
- 既定では、閉じるボタンは常に、閉じるタブに対して表示されます。 この動作を変更するには、 CloseButtonOverlayMode プロパティを
OnPointerOver
に設定できます。 この場合、選択したタブは常に閉じるボタンを表示しますが、選択されていないタブでは、タブが閉じられ、ユーザーがその上にポインターを置いている場合にのみ閉じるボタンが表示されます。 - TabWidthMode プロパティを設定して、タブのサイズを変更できます。 (
TabViewItem
では、Width
プロパティは無視されます)。TabViewWidthMode 列挙型のオプションは次のとおりです。Equal
- 各タブの幅は同じです。 これが既定値です。SizeToContent
- 各タブは、タブ内のコンテンツに合わせて幅を調整します。Compact
- 選択されていないタブが折りたたまれると、そのアイコンのみが表示されます。 選択したタブが調整され、タブ内のコンテンツが表示されます。
コンテンツ
選択したタブに表示される要素は、TabViewItem の Content プロパティに追加されます。 TabViewItem は ContentControl
この記事の例では、XAML の Content
要素にテキストを直接追加する簡単なケースを示します。 ただし、実際の UI は通常、より複雑です。 タブのコンテンツとして複雑な UI を追加する一般的な方法は、 それを UserControl または Page にカプセル化し、それを TabViewItem のコンテンツとして追加することです。 この例では、アプリに PictureSettingsControl
という XAML UserControl があることを前提としています。
<TabViewItem>
<TabViewItem.Content>
<local:PictureSettingsControl/>
</TabViewItem.Content>
</TabViewItem>
静的タブ
この例では、2 つの静的タブを含む単純な TabView を示します。 どちらのタブ項目も、TabView のコンテンツとして XAML に追加されます。
TabView を静的にするには、次の設定を使用します。
- IsAddTabButtonVisible プロパティを
false
に設定すると、タブの追加ボタンが非表示になり、AddTabButtonClick イベントが発生しないようにすることができます。 - CanReorderTabs プロパティを
false
に設定すると、ユーザーがタブを別の順序にドラッグできなくなります。 - 各 TabViewItem で IsClosable プロパティを false に設定すると、 Tab Close ボタンが非表示にされ、ユーザー が 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_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 static
プロパティを追加します。 ( ユーザー インターフェイスの移行を参照してください)。
public partial class App : Application
{
// ... code removed.
// Add this.
public static Window Window { get { return m_window; } }
// Update this to make it static.
private static Window m_window;
}
次に、TabView からすべてのタブが削除されている場合に Window.Close を呼び出す TabCloseRequested イベント ハンドラーを変更します。
// 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)
{
App.Window.Close();
}
}
注
この例は、1 つのウィンドウ (MainWindow
) を持つアプリに対して機能します。 アプリに複数のウィンドウがある場合、またはタブの破棄を有効にしている場合は、ウィンドウを追跡し、閉じる正しいウィンドウを見つける必要があります。 この例については、次のセクションを参照してください。
タブの引き裂き
タブの破棄 は、ユーザーが TabView のタブ ストリップからタブをドラッグして別の TabView コントロール (通常は新しいウィンドウ) に移動した場合の動作を示します。
Windows App SDK 1.6 以降、TabView には CanTearOutTabs プロパティがあり、タブを新しいウィンドウにドラッグするエクスペリエンスを強化するために設定できます。 このオプションを有効にしてタブ ストリップの外にタブをドラッグすると、ドラッグ中に新しいウィンドウがすぐに作成され、ユーザーはウィンドウを画面の端にドラッグして、ウィンドウ を 1 つのスムーズなモーションで最大化または
CanTearOutTabs プロパティをtrue
に設定すると、ドラッグ アンド ドロップ イベントではなくタブの破棄イベントが発生します。 タブの破棄を実装するには、次のイベントを処理する必要があります。
-
このイベントは、タブがタブ ストリップから最初にドラッグされたときに発生します。 これを処理して、タブが移動される新しいウィンドウと TabView を作成します。
-
このイベントは、新しいウィンドウが指定された後に発生します。 これを処理して、元の TabView から新しいウィンドウの TabView に引き裂かれたタブを移動します。
-
このイベントは、引き裂かれたタブが既存の TabView の上にドラッグされたときに発生します。 タブを受け入れるかどうかを示すために、引き裂かれたタブを受け取っている TabView でそれを処理します。
-
このイベントは、引き裂かれたタブが既存の TabView の上にドラッグされ、
ExternalTornOutTabsDropping
イベントによってドロップが許可されていることが示された場合に発生します。 元の TabView からタブを削除し、指定したインデックス位置にある受信 TabView に挿入するために、引き裂かれたタブを受信している TabView で処理します。
TabDragStarting、TabStripDragOver、TabStripDrop、TabDragCompleted、TabDroppedOutside のタブティアアウトが有効になっている場合、これらのイベントは発生しません。
注意
管理者として管理者特権で実行されているプロセスでは、タブの破棄がサポートされます。
次の例では、タブの破棄をサポートするイベント ハンドラーを実装する方法を示します。
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 ギャラリー リポジトリ ( WindowHelper.cs) からコピーできます。 タブの破棄を実装するには、このヘルパー クラスをお勧めします。その使用方法については、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 には、 TabTearOutRequested
イベント ハンドラーで引き裂かれたタブを移動する TabView コントロールが含まれている必要があります。
ヒント
この例では、空の TabView のみが含まれるため、新しい MainPage
クラスを作成します (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 にドラッグする
前の手順で示したように、タブが引き裂かれ、新しいウィンドウに配置されると、次の 2 つのいずれかが発生する可能性があります。
- ユーザーはタブを削除でき、新しいウィンドウに残ります。 分離プロセスはここで終了し、これ以上のイベントは発生しません。
- ユーザーは引き続き取り外されたタブを既存の TabView コントロールにドラッグできます。 この場合、プロセスが続行され、さらにいくつかのイベントが発生して、元の TabView からタブを削除し、既存の TabView に外部タブを挿入できます。
タブが既存の TabView の上にドラッグされると、 ExternalTornOutTabsDropping イベントが発生します。 イベント ハンドラーでは、この TabView にタブを挿入できるかどうかを判断できます。 ほとんどの場合、 args.
AllowDrop プロパティを true
に設定するだけで済む場合があります。 ただし、そのプロパティを設定する前にチェックを実行する必要がある場合は、ここで行うことができます。 AllowDrop
がfalse
に設定されている場合、タブドラッグアクションは続行され、ExternalTornOutTabsDropped イベントは発生しません。
private void TabView_ExternalTornOutTabsDropping(TabView sender,
TabViewExternalTornOutTabsDroppingEventArgs args)
{
args.AllowDrop = true;
}
AllowDrop
が true
イベント ハンドラーで ExternalTornOutTabsDropping
に設定されている場合、ExternalTornOutTabsDropped
イベントが直ちに発生します。
注
イベント名の Dropped
は、ドラッグ アンド ドロップ API の ドロップ アクションの概念に直接対応していません。 ここでは、 ユーザーがドロップ アクションを実行するためにタブを離す必要はありません。 タブがタブ ストリップの上に保持されている間にイベントが発生し、TabView にタブを ドロップ するコードが実行されます。
ExternalTornOutTabsDropped イベント ハンドラーは、TabTearOutRequested イベントと同じパターンに従いますが、反転されます。元の TabView からタブを削除し、sender
TabView に挿入する必要があります。
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 を使用している場合は、GetParentTabView
ではなく、ツールキットの DependencyObjectExtensions で FindAscendant
ヘルパー メソッドを使用できます。
ウィンドウのタイトル バーに TabView タブを表示する
ウィンドウのタイトル バーの下にタブが独自の行を占有する代わりに、2 つを同じ領域にマージできます。 これにより、コンテンツの縦方向の領域が節約され、最新のアプリの感じになります。
ユーザーはタイトル バーでウィンドウをドラッグしてウィンドウの位置を変更できるため、タイトル バーがタブで完全に埋め込まれていないことが重要です。 したがって、タイトル バーにタブを表示する場合は、ドラッグ可能領域として予約するタイトル バーの一部を指定する必要があります。 ドラッグ可能領域を指定しない場合、タイトル バー全体がドラッグ可能になり、タブが入力イベントを受信できなくなります。 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)
{
App.Window.ExtendsContentIntoTitleBar = true;
App.Window.SetTitleBar(CustomDragRegion);
CustomDragRegion.MinWidth = 188;
}
注
ウィンドウへの参照を取得する方法は、アプリでウィンドウを追跡する方法によって異なる場合があります。 詳細については、この記事の「 最後のタブを閉じたときにウィンドウを閉じる 」 と「新しいウィンドウを作成して追跡する」 を参照してください。
開発者向けのキーボード ガイダンス
ヒント
組み込みのキーボード サポートの詳細については、この記事の「 キーボード ナビゲーション 」を参照してください。
アプリケーションによっては、より高度なキーボード制御が必要になる場合があります。 アプリに適している場合は、次のショートカットを実装することを検討してください。
警告
既存のアプリに TabView を追加する場合は、推奨される TabView キーボード ショートカットのキーの組み合わせに対応するキーボード ショートカットが既に作成されている可能性があります。 この場合は、既存のショートカットを保持するか、ユーザーに直感的なタブ エクスペリエンスを提供するかを、検討する必要があります。
- Ctrl + T キーを押 して新しいタブを開きます。通常、このタブには定義済みのドキュメントが設定されているか、コンテンツを簡単に選択できる空のタブが作成されます。 ユーザーが新しいタブのコンテンツを選択する必要がある場合は、コンテンツ選択コントロールに入力フォーカスを設定することを検討します。
- Ctrl + W キーを押 すと、選択したタブが閉じます。TabView では次のタブが自動的に選択されることに注意してください。
- Ctrl + Shift + T キー を押して最近閉じたタブを開く必要があります (または、より正確には、最近閉じたタブと同じ内容の新しいタブを開きます)。 最後に閉じられたタブから始めて、ショートカットが呼び出されるたびに、時間を遡って移動します。 これには、最近閉じられたタブのリストを保持する必要があることに注意してください。
- Ctrl + 1 キーを押して、タブリストの最初のタブを選択します。 同様に、Ctrl + 2 キーが押されたら 2 番目のタブを選択し、Ctrl + 3 キーが押されたら 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 is not 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;
if (tab is not null)
{
CloseSelectedTab(tabView, tab);
}
args.Handled = true;
}
private void TabView_TabCloseRequested(TabView sender, TabViewTabCloseRequestedEventArgs args)
{
CloseSelectedTab(sender, args.Tab);
}
private void CloseSelectedTab(TabView tabView, TabViewItem tab)
{
// Only remove the selected tab if it can be closed.
if (tab.IsClosable == true)
{
tabView.TabItems.Remove(tab);
}
}
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
重要
この記事の情報と例は、
このセクションには、UWP または WinUI 2 アプリでコントロールを使用するために必要な情報が含まれています。
UWP アプリの TabView コントロールは、WinUI 2 の一部として含まれています。 インストール手順を含む詳細については、WinUI 2
タブティアアウト API は、WinUI 2 バージョンの TabView には含まれません。
WinUI 2 API: TabView クラス 、TabViewItem クラス - WinUI 2 ギャラリー アプリを開き、TabView の動作を確認します。 WinUI 2 ギャラリー アプリには、ほとんどの 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 />
関連記事
Windows developer