Tabview

Kontrol TabView adalah cara untuk menampilkan sekumpulan tab dan kontennya masing-masing. TabView berguna untuk menampilkan beberapa halaman (atau dokumen) konten sambil memberi pengguna kemampuan untuk mengatur ulang, membuka, atau menutup tab baru.

Contoh TabView

Mendapatkan Pustaka UI Windows

Logo WinUI

Kontrol TabView memerlukan Pustaka UI Windows, paket NuGet yang berisi kontrol dan fitur UI baru untuk aplikasi Windows. Untuk informasi selengkapnya, termasuk instruksi penginstalan, lihat Pustaka Windows UI.

API Pustaka UI Windows: kelas TabView, kelas TabViewItem

Tip

Di seluruh dokumen ini, kami menggunakan alias muxc di XAML untuk mewakili API Pustaka UI Windows yang telah kami sertakan dalam proyek kami. Kami telah menambahkan ini ke elemen Halaman kami: xmlns:muxc="using:Microsoft.UI.Xaml.Controls"

Di kode belakang, kami juga menggunakan alias muxc di C# untuk mewakili Api Pustaka UI Windows yang telah kami sertakan dalam proyek kami. Kami telah menambahkan ini menggunakan pernyataan di bagian atas file: using muxc = Microsoft.UI.Xaml.Controls;

Apakah ini kontrol yang tepat?

Secara umum, UI bertab hadir dalam salah satu dari dua gaya berbeda yang berbeda dalam fungsi dan tampilan: Tab statis adalah jenis tab yang sering ditemukan di jendela pengaturan. Mereka berisi sejumlah halaman dalam urutan tetap yang biasanya berisi konten yang telah ditentukan sebelumnya. Tab dokumen adalah jenis tab yang ditemukan di browser, seperti Microsoft Edge. Pengguna dapat membuat, menghapus, dan mengatur ulang tab; pindahkan tab antar jendela; dan ubah konten tab.

TabView menawarkan tab dokumen untuk aplikasi UWP. Gunakan TabView saat:

  • Pengguna akan dapat membuka, menutup, atau menyusun ulang tab secara dinamis.
  • Pengguna akan dapat membuka dokumen atau halaman web langsung ke tab.
  • Pengguna akan dapat menyeret dan meletakkan tab di antara jendela.

Jika TabView tidak sesuai untuk aplikasi Anda, pertimbangkan untuk menggunakan kontrol NavigationView .

anatomi

Gambar di bawah ini menunjukkan bagian-bagian kontrol TabView . TabStrip memiliki header dan footer, tetapi tidak seperti dokumen, header dan footer TabStrip masing-masing berada di ujung kiri dan paling kanan strip.

Anatomi kontrol TabView

Gambar berikutnya menunjukkan bagian-bagian kontrol TabViewItem . Perhatikan bahwa meskipun konten ditampilkan di dalam kontrol TabView, konten sebenarnya adalah bagian dari TabViewItem.

Anatomi kontrol TabViewItem

Membuat tampilan tab

Contoh ini membuat TabView sederhana bersama dengan penanganan aktivitas untuk mendukung tab pembuka dan penutupan.

 <muxc:TabView AddTabButtonClick="TabView_AddTabButtonClick"
               TabCloseRequested="TabView_TabCloseRequested"/>
// Add a new Tab to the TabView
private void TabView_AddTabButtonClick(muxc.TabView sender, object args)
{
    var newTab = new muxc.TabViewItem();
    newTab.IconSource = new muxc.SymbolIconSource() { Symbol = Symbol.Document };
    newTab.Header = "New Document";

    // The Content of a TabViewItem is often a frame which hosts a page.
    Frame frame = new Frame();
    newTab.Content = frame;
    frame.Navigate(typeof(Page1));

    sender.TabItems.Add(newTab);
}

// Remove the requested tab from the TabView
private void TabView_TabCloseRequested(muxc.TabView sender, muxc.TabViewTabCloseRequestedEventArgs args)
{
    sender.TabItems.Remove(args.Tab);
}

Aktivitas

Ada beberapa cara untuk memanfaatkan atau memperluas fungsionalitas TabView.

Ikat TabItemsSource ke TabViewItemCollection

<muxc:TabView TabItemsSource="{x:Bind TabViewItemCollection}" />

Menampilkan tab TabView di bilah judul jendela

Alih-alih memiliki tab yang menempati barisnya sendiri di bawah bilah judul Jendela, Anda dapat menggabungkan keduanya ke area yang sama. Ini menghemat ruang vertikal untuk konten Anda, dan memberi aplikasi Anda nuansa modern.

Karena pengguna dapat menyeret jendela dengan bilah judulnya untuk memposisikan ulang Jendela, penting bahwa bilah judul tidak sepenuhnya diisi dengan Tab. Oleh karena itu, saat menampilkan tab di bilah judul, Anda harus menentukan sebagian bilah judul yang akan dicadangkan sebagai area yang dapat diseret. Jika Anda tidak menentukan wilayah yang dapat diseret, seluruh bilah judul akan dapat diseret, yang akan mencegah tab Anda menerima peristiwa input. Jika TabView Anda akan ditampilkan di bilah judul jendela, Anda harus selalu menyertakan TabStripFooter di TabView Anda dan menandainya sebagai wilayah yang dapat diseret.

Untuk informasi selengkapnya, lihat Kustomisasi bilah judul

Tab dalam bilah judul

<muxc:TabView HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    <muxc:TabViewItem Header="Home" IsClosable="False">
        <muxc:TabViewItem.IconSource>
            <muxc:SymbolIconSource Symbol="Home" />
        </muxc:TabViewItem.IconSource>
    </muxc:TabViewItem>
    <muxc:TabViewItem Header="Document 0">
        <muxc:TabViewItem.IconSource>
            <muxc:SymbolIconSource Symbol="Document" />
        </muxc:TabViewItem.IconSource>
    </muxc:TabViewItem>
    <muxc:TabViewItem Header="Document 1">
        <muxc:TabViewItem.IconSource>
            <muxc:SymbolIconSource Symbol="Document" />
        </muxc:TabViewItem.IconSource>
    </muxc:TabViewItem>
    <muxc:TabViewItem Header="Document 2">
        <muxc:TabViewItem.IconSource>
            <muxc:SymbolIconSource Symbol="Document" />
        </muxc:TabViewItem.IconSource>
    </muxc:TabViewItem>

    <muxc:TabView.TabStripHeader>
        <Grid x:Name="ShellTitlebarInset" Background="Transparent" />
    </muxc:TabView.TabStripHeader>
    <muxc:TabView.TabStripFooter>
        <Grid x:Name="CustomDragRegion" Background="Transparent" />
    </muxc:TabView.TabStripFooter>
</muxc:TabView>
public MainPage()
{
    this.InitializeComponent();

    var coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
    coreTitleBar.ExtendViewIntoTitleBar = true;
    coreTitleBar.LayoutMetricsChanged += CoreTitleBar_LayoutMetricsChanged;

    Window.Current.SetTitleBar(CustomDragRegion);
}

private void CoreTitleBar_LayoutMetricsChanged(CoreApplicationViewTitleBar sender, object args)
{
    if (FlowDirection == FlowDirection.LeftToRight)
    {
        CustomDragRegion.MinWidth = sender.SystemOverlayRightInset;
        ShellTitlebarInset.MinWidth = sender.SystemOverlayLeftInset;
    }
    else
    {
        CustomDragRegion.MinWidth = sender.SystemOverlayLeftInset;
        ShellTitlebarInset.MinWidth = sender.SystemOverlayRightInset;
    }

    CustomDragRegion.Height = ShellTitlebarInset.Height = sender.Height;
}

Catatan

Untuk memastikan bahwa tab di bilah judul tidak terpaku oleh konten shell, Anda harus memperhitungkan overlay kiri dan kanan. Di tata letak LTR, inset yang tepat menyertakan tombol caption dan wilayah seret. Kebalikannya adalah benar dalam RTL. Nilai SystemOverlayLeftInset dan SystemOverlayRightInset berada dalam hal fisik kiri dan kanan, jadi balikkan ini juga ketika berada di RTL.

Mengontrol perilaku luapan

Saat bilah tab menjadi ramai dengan tab, Anda dapat mengontrol bagaimana tab ditampilkan dengan mengatur TabView.TabWidthMode.

Nilai TabWidthMode Aktivitas
Equal Saat tab baru ditambahkan, semua tab akan menyusut secara horizontal hingga mencapai lebar minimum yang sangat kecil.
SizeToContent Tab akan selalu menjadi "ukuran alami", ukuran minimum yang diperlukan untuk menampilkan ikon dan header mereka. Mereka tidak akan memperluas atau menyusut saat tab ditambahkan atau ditutup.

Nilai apa pun yang Anda pilih, akhirnya mungkin ada terlalu banyak tab untuk ditampilkan di strip tab Anda. Dalam hal ini, bumper gulir akan muncul yang memungkinkan pengguna untuk menggulir TabStrip ke kiri dan kanan.

Panduan untuk pemilihan Tab

Sebagian besar pengguna memiliki pengalaman menggunakan tab dokumen hanya dengan menggunakan browser web. Saat mereka menggunakan tab dokumen di aplikasi Anda, pengalaman mereka menginformasikan harapan mereka tentang bagaimana tab Anda harus beraksi.

Tidak peduli bagaimana pengguna berinteraksi dengan sekumpulan tab dokumen, harus selalu ada tab aktif. Jika pengguna menutup tab yang dipilih atau memecah tab yang dipilih keluar ke jendela lain, tab lain harus menjadi tab aktif. TabView mencoba melakukan ini secara otomatis memilih tab berikutnya. Jika Anda memiliki alasan yang baik bahwa aplikasi Anda harus mengizinkan TabView dengan tab yang tidak dipilih, area konten TabView hanya akan kosong.

Navigasi papan ketik

TabView mendukung banyak skenario navigasi keyboard umum secara default. Bagian ini menjelaskan fungsionalitas bawaan, dan memberikan rekomendasi tentang fungsionalitas tambahan yang mungkin berguna untuk beberapa aplikasi.

Perilaku kunci tab dan kursor

Saat fokus berpindah ke area TabStrip , TabViewItem yang dipilih mendapatkan fokus. Pengguna kemudian dapat menggunakan tombol panah Kiri dan Kanan untuk memindahkan fokus (bukan pilihan) ke tab lain di TabStrip. Fokus panah terperangkap di dalam strip tab dan tombol tambahkan tab (+), jika ada. Untuk memindahkan fokus keluar dari area TabStrip, pengguna dapat menekan tombol Tab yang akan memindahkan fokus ke elemen yang dapat difokuskan berikutnya.

Memindahkan fokus melalui Tab

Memindahkan fokus melalui tab

Tombol panah tidak memfokuskan siklus

Tombol panah tidak memfokuskan siklus

Memilih tab

Saat TabViewItem memiliki fokus, menekan Spasi atau Enter akan memilih TabViewItem tersebut.

Gunakan tombol panah untuk memindahkan fokus, lalu tekan Spasi untuk memilih tab.

Spasi untuk memilih tab

Pintasan untuk memilih tab yang berdekatan

Ctrl+Tab akan memilih TabViewItem berikutnya. Ctrl+Shift+Tab akan memilih TabViewItem sebelumnya. Untuk tujuan ini, daftar tab "diulang", jadi memilih tab berikutnya, tab terakhir dipilih akan menyebabkan tab pertama dipilih.

Menutup tab

Menekan Ctrl + F4 akan menaikkan peristiwa TabCloseRequested . Tangani peristiwa dan tutup tab jika sesuai.

Panduan keyboard untuk Pengembang Aplikasi

Beberapa aplikasi mungkin memerlukan kontrol keyboard yang lebih canggih. Pertimbangkan untuk menerapkan pintasan berikut jika sesuai untuk aplikasi Anda.

Peringatan

Jika Anda menambahkan TabView ke aplikasi yang sudah ada, Anda mungkin telah membuat pintasan keyboard yang memetakan ke kombinasi tombol pintasan keyboard TabView yang direkomendasikan. Dalam hal ini, Anda harus mempertimbangkan apakah akan menyimpan pintasan yang ada atau menawarkan pengalaman tab yang intuitif bagi pengguna.

  • Ctrl + T akan membuka tab baru. Umumnya tab ini diisi dengan dokumen yang telah ditentukan sebelumnya, atau dibuat kosong dengan cara sederhana untuk memilih kontennya. Jika pengguna harus memilih konten untuk tab baru, pertimbangkan untuk memberikan fokus input ke kontrol pemilihan konten.
  • Ctrl + W akan menutup tab yang dipilih. Ingat, TabView akan memilih tab berikutnya secara otomatis.
  • Ctrl + Shift + T harus membuka tab yang baru ditutup (atau lebih akurat, buka tab baru dengan konten yang sama seperti tab yang baru ditutup). Mulailah dengan tab yang terakhir ditutup, dan pindah mundur tepat waktu untuk setiap kali pintasan dipanggil. Perhatikan bahwa ini akan memerlukan pemeliharaan daftar tab yang baru saja ditutup.
  • Ctrl + 1 harus memilih tab pertama di daftar tab. Demikian juga, Ctrl + 2 harus memilih tab kedua, Ctrl + 3 harus memilih yang ketiga, dan sebagainya melalui Ctrl + 8.
  • Ctrl + 9 harus memilih tab terakhir dalam daftar tab, terlepas dari berapa banyak tab dalam daftar.
  • Jika tab menawarkan lebih dari sekadar perintah tutup (seperti menduplikasi atau menyematkan tab), gunakan menu konteks untuk menampilkan semua tindakan yang tersedia yang dapat dilakukan pada tab.

Menerapkan perilaku keyboard gaya browser

Contoh ini mengimplementasikan sejumlah rekomendasi di atas pada TabView. Secara khusus, Contoh ini mengimplementasikan Ctrl + T, Ctrl + W, Ctrl + 1-8, dan Ctrl + 9.

<muxc:TabView x:Name="TabRoot">
    <muxc: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" />
    </muxc:TabView.KeyboardAccelerators>
    <!-- ... some tabs ... -->
</muxc:TabView>
private void NewTabKeyboardAccelerator_Invoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args)
{
    // Create new tab.
    var newTab = new muxc.TabViewItem();
    newTab.IconSource = new muxc.SymbolIconSource() { Symbol = Symbol.Document };
    newTab.Header = "New Document";

    // The Content of a TabViewItem is often a frame which hosts a page.
    Frame frame = new Frame();
    newTab.Content = frame;
    frame.Navigate(typeof(Page1));

    TabRoot.TabItems.Add(newTab);
}

private void CloseSelectedTabKeyboardAccelerator_Invoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args)
{
    // Only remove the selected tab if it can be closed.
    if (((muxc.TabViewItem)TabRoot.SelectedItem).IsClosable)
    {
        TabRoot.TabItems.Remove(TabRoot.SelectedItem);
    }
}

private void NavigateToNumberedTabKeyboardAccelerator_Invoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args)
{
    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 = TabRoot.TabItems.Count - 1;
            break;
    }

    // Only select the tab if it is in the list
    if (tabToSelect < TabRoot.TabItems.Count)
    {
        TabRoot.SelectedIndex = tabToSelect;
    }
}