Compartilhar via


Visualização de abas

O controle TabView é uma maneira de exibir um conjunto de guias e seu respectivo conteúdo. Os controles TabView são úteis para exibir várias páginas (ou documentos) de conteúdo, permitindo que um usuário reorganize, feche ou abra novas guias.

Exemplo de um TabView

Esse é o controle correto?

Em geral, as interfaces com abas vêm em um dos dois estilos distintos que diferem na função e na aparência.

  • Guias estáticas são o tipo de guias frequentemente encontradas nas janelas de configurações. Elas contêm um número definido de páginas em uma ordem fixa que geralmente contém conteúdo predefinido.
  • As guias do documento são o tipo de guias encontrado em um navegador, como o Microsoft Edge. Os usuários podem criar, remover e reorganizar guias; mover guias entre janelas; e alterar o conteúdo das guias.

Por padrão, TabView é configurado para fornecer guias de documento. Recomendamos o TabView quando os usuários poderão:

  • Abra, feche ou reorganize dinamicamente as guias.
  • Abra documentos ou páginas da Web diretamente em abas.
  • Arraste e solte as guias entre janelas.

A API TabView permite configurar o controle para guias estáticas. No entanto, para seguir as diretrizes de design do Windows e se houver mais de alguns itens de navegação estáticos, considere usar um controle NavigationView .

Anatomia

A interface do usuário com guias é criada com um controle TabView e um ou mais controles TabViewItem. O TabView hospeda instâncias de TabViewItem, que representam uma única aba e seu conteúdo.

Partes do TabView

Esta imagem mostra as partes do controle TabView . A faixa de tabulação tem um cabeçalho e rodapé, mas ao contrário de um documento, o cabeçalho e o rodapé da faixa de tabulação estão na extrema esquerda e na extrema direita da faixa, respectivamente.

Esta imagem mostra as partes do controle de visualização de abas. A barra de abas contém quatro guias e tem um cabeçalho e rodapé, que estão na extrema esquerda e extrema direita da barra, respectivamente.

Partes do TabViewItem

Esta imagem mostra as partes do controle TabViewItem . Embora o conteúdo seja exibido dentro do controle TabView, o conteúdo é, na verdade, uma parte do TabViewItem.

Esta imagem mostra as partes do controle de item de exibição de guia. Uma guia individual é selecionada, que tem um ícone e um rótulo, com uma área de conteúdo abaixo da guia.

Recommendations

Seleção de aba

A maioria dos usuários tem experiência com o uso de guias de documentos simplesmente usando um navegador da Web. Quando eles usam guias de documentos em seu aplicativo, a experiência deles informa suas expectativas para a maneira como as guias devem se comportar.

Independentemente de como o usuário interage com um conjunto de guias de documento, sempre deve haver uma guia ativa. Se o usuário fechar a guia selecionada ou dividir a guia selecionada em outra janela, outra guia deverá se tornar a guia ativa. TabView tenta fazer isso automaticamente selecionando a próxima guia. Se você tiver um bom motivo para que seu aplicativo permita um TabView com uma guia não selecionada, a área de conteúdo do TabView ficará simplesmente em branco.

Navegação por teclado

O TabView é compatível com muitos cenários de navegação de teclado comuns por padrão. Esta seção explica a funcionalidade interna e fornece recomendações sobre funcionalidades adicionais que podem ser úteis para alguns aplicativos.

Comportamento-chave da guia e do cursor

Quando o foco passa para a área TabStrip, o TabViewItem selecionado ganha foco. Em seguida, o usuário pode usar as teclas de seta para a esquerda e para a direita para transferir o foco (não a seleção) para outras guias na barra de guias. O foco da seta é interceptado dentro da faixa de guias e do botão adicionar guia (+), se houver um. Para mover o foco para fora da área de faixa de tabulação, o usuário pode pressionar a tecla Tab , que moverá o foco para o próximo elemento focalizável.

Mover o foco pela tecla Tab

Mover o foco por meio da tecla Tab

As teclas de seta não circulam alternam o foco

As teclas de seta não alternam o foco

Selecionar uma guia

Quando um TabViewItem tiver foco, pressione Space ou Enter para selecionar o TabViewItem.

Use teclas de direção para mover o foco e pressione Espaço para selecionar a guia.

Espaço para selecionar aba

Atalhos para selecionar guias adjacentes

Pressione Ctrl+Tab para selecionar o próximo TabViewItem. Pressione Ctrl+Shift+Tab para selecionar o TabViewItem anterior. Para essas finalidades, a lista de guias é "em loop", portanto, selecionar a próxima guia enquanto a última guia estiver selecionada fará com que a primeira guia seja selecionada.

Fechar uma guia

Pressione Ctrl + F4 para acionar o evento TabCloseRequested . Manipule o evento e feche a guia, se apropriado.

Dica

Para obter mais informações, consulte as diretrizes de teclado para desenvolvedores posteriormente neste artigo.

Criar um modo de exibição de guia

O aplicativo Galeria da WinUI 3 inclui exemplos interativos da maioria dos controles, recursos e funcionalidades da WinUI 3. Obtenha o aplicativo na Microsoft Store ou obtenha o código-fonte no GitHub

Os exemplos nesta seção mostram várias maneiras de configurar um controle TabView .

Itens de visualização de guia

Cada guia em um TabView é representada por um controle TabViewItem , que inclui a guia mostrada na faixa de tabulação e o conteúdo mostrado abaixo da faixa de guias.

Configurar uma aba

Para cada TabViewItem, você pode definir um cabeçalho e um ícone e especificar se o usuário pode fechar a guia.

  • A propriedade Header normalmente é definida como um valor de cadeia de caracteres que fornece um rótulo descritivo para a guia. No entanto, a Header propriedade pode ser qualquer objeto. Você também pode usar a propriedade HeaderTemplate para especificar um DataTemplate que define como os dados de cabeçalho associados devem ser exibidos.
  • Defina a propriedade IconSource para especificar um ícone para a guia.
  • Por padrão, a guia mostra um botão fechar (X). Você pode definir a propriedade IsClosable como false para ocultar o botão de fechar e garantir que um usuário não possa fechar a guia. (Se você fechar as guias no código do aplicativo fora de um evento de pedido de fechamento, primeiro verifique se IsClosable é true.)

Para o TabView, você pode configurar várias opções que se aplicam a todas as guias.

  • Por padrão, o botão de fechar é sempre mostrado para guias fecháveis. Você pode definir a propriedade CloseButtonOverlayMode para OnPointerOver alterar esse comportamento. Nesse caso, a guia selecionada sempre mostra o botão de fechar se puder ser fechada, mas as guias não selecionadas mostram o botão de fechar apenas quando puderem ser fechadas e o usuário tiver o ponteiro sobre elas.
  • Você pode definir a propriedade TabWidthMode para alterar o tamanho das guias. (A Width propriedade é ignorada em TabViewItem.) Estas são as opções na enumeração TabViewWidthMode :
    • Equal - Cada aba tem a mesma largura. Esse é o padrão.
    • SizeToContent - Cada guia ajusta sua largura ao conteúdo dentro da guia.
    • Compact – as guias não selecionadas são recolhidas para mostrar apenas seu ícone. A guia selecionada é ajustada para exibir o conteúdo dentro da guia.

Content

Os elementos exibidos na guia selecionada são adicionados à propriedade Content do TabViewItem. TabViewItem é um ContentControl, portanto, você pode adicionar qualquer tipo de objeto como conteúdo. Você também pode aplicar um DataTemplate à propriedade ContentTemplate . Consulte a classe ContentControl para obter mais informações.

Os exemplos neste artigo mostram um caso simples de adição de texto diretamente ao Content elemento em XAML. No entanto, a interface do usuário real normalmente é mais complexa. Uma maneira comum de adicionar interface do usuário complexa como o conteúdo de uma guia é encapsulá-la em um UserControl ou em uma página e adicioná-la como o conteúdo do TabViewItem. Este exemplo pressupõe que seu aplicativo tenha um UserControl XAML chamado PictureSettingsControl.

<TabViewItem>
    <TabViewItem.Content>
        <local:PictureSettingsControl/>
    </TabViewItem.Content>
</TabViewItem>

Guias estáticas

Este exemplo mostra um TabView simples com duas guias estáticas. Ambos os itens de guia são adicionados em XAML como conteúdo do TabView.

Para tornar um TabView estático, use estas configurações:

<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>

Guias de documento

Por padrão, o TabView é configurado para guias de documento. O usuário pode adicionar novas guias, reorganizar guias e fechar guias. Nessa configuração, você precisa lidar com os eventos AddTabButtonClick e TabCloseRequested para habilitar a funcionalidade.

Quando guias são adicionadas a um TabView, pode eventualmente haver guias demais para serem exibidas na barra de guias. Nesse caso, serão exibidos indicadores de rolagem que permitem que o usuário role a barra de guias para a esquerda e a direita para acessar guias ocultas.

Este exemplo cria um TabView simples junto com manipuladores de evento para abrir e fechar guias. O TabView_AddTabButtonClick manipulador de eventos mostra como adicionar um TabViewItem no código.

<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);
}

Fechar a janela quando a última guia for fechada

Se todas as guias em seu aplicativo puderem ser fechadas e a janela do aplicativo deva ser fechada quando a última guia for fechada, você também deverá fechar a janela no manipulador de eventos TabCloseRequested.

Primeiro, no arquivo App.xaml.cs, adicione uma propriedade public static que permitirá acessar a instância Window do Page que hospeda o TabView. (Consulte Acompanhar a janela atual na visão geral do Windowing.)

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;
}

Em seguida, modifique o manipulador de eventos TabCloseRequested para chamar Window.Close se todas as guias tiverem sido removidas do 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)
    {
        App.Window.Close();
    }
}

Observação

Este exemplo funciona para um aplicativo com uma única janela (MainWindow). Se o aplicativo tiver várias janelas ou você tiver habilitado o destacamento de aba, você precisará rastrear as janelas e, em seguida, encontrar a correta para fechar. Consulte a próxima seção para obter um exemplo disso.

Separador de abas

Destacar guia descreve o que acontece quando um usuário arrasta uma guia para fora da barra de guias de TabView e a move para outro controle de TabView, normalmente em uma nova janela.

A partir do SDK do Aplicativo Windows 1.6, TabView tem uma propriedade CanTearOutTabs que você pode definir para fornecer uma experiência aprimorada para arrastar guias para uma nova janela. Quando um usuário arrasta uma guia para fora da faixa de guias quando essa opção está habilitada, uma nova janela é criada imediatamente durante essa operação, permitindo que o usuário a arraste até a borda da tela para maximizar ou ajustar a janela em um movimento suave. Essa implementação também não usa APIs de arrastar e soltar, portanto, não é afetada por nenhuma limitação nessas APIs.

Quando você define a propriedade CanTearOutTabs como true, ela faz com que os eventos de destacar guias sejam realizados em vez de eventos de arrastar e soltar. Para implementar o destaque da guia, você deve manipular esses eventos:

  • TabTearOutWindowRequested

    Esse evento ocorre quando uma guia é arrastada pela primeira vez para fora da barra de guias. Manipule-o para criar uma nova Janela e TabView para a qual a guia será movida.

  • TabTearOutRequested

    Esse evento ocorre depois que uma nova janela é fornecida. Manipule-o para mover a guia destacada de TabView de origem para um TabView na nova janela.

  • ExternoTornOutTabsDropping

    Esse evento ocorre quando uma guia rasgada é arrastada sobre um TabView existente. Manipule-o no TabView que está recebendo a guia destacada para indicar se a guia deve ou não ser aceita.

  • ExternoTornOutTabsDropped

    Esse evento ocorre quando uma guia destacada é arrastada sobre um TabView existente e o evento ExternalTornOutTabsDropping indica que a ação de soltar é permitida. Manipule-o no TabView que está recebendo a guia destacada para remover a guia de TabView de origem e inseri-la no TabView de destino no índice especificado.

Esses eventos não são gerados quando o destaque de guia está habilitado: TabDragStarting, TabStripDragOver, TabStripDrop, TabDragCompleted e TabDroppedOutside.

Cuidado

A remoção de tabulação é suportada em processos executados com privilégios elevados como Administrador.

Os exemplos a seguir mostram como implementar os manipuladores de eventos para dar suporte ao destaque de guia.

Configurar o TabView

Esse XAML define a propriedade CanTearOutTabs como true e configura os manipuladores de eventos de destaque de guias.

<TabView x:Name="tabView"
     CanTearOutTabs="True"
     TabTearOutWindowRequested="TabView_TabTearOutWindowRequested"
     TabTearOutRequested="TabView_TabTearOutRequested"
     ExternalTornOutTabsDropping="TabView_ExternalTornOutTabsDropping"
     ExternalTornOutTabsDropped="TabView_ExternalTornOutTabsDropped">
    <!-- TabView content -->
</TabView>

Criar e acompanhar uma nova janela

O destaque da guia requer que você crie e gerencie novas janelas em seu aplicativo.

Dica

O aplicativo Da Galeria do WinUI inclui uma WindowHelper classe que facilita o gerenciamento de janelas em seu aplicativo. Você pode copiá-lo do GitHub no repositório da Galeria WinUI: WindowHelper.cs. Recomendamos que essa classe auxiliar implemente o destaque de guia. Consulte o TabViewWindowingSamplePage no GitHub para ver como ele é usado.

Neste artigo, os métodos auxiliares são copiados de WindowHelper.cs, mas são modificados e mostrados de forma direta para legibilidade.

Aqui, uma lista para acompanhar todas as janelas ativas é criada em App.xaml.cs. O OnLaunched método é atualizado para acompanhar a janela após sua criação. (Isso não será necessário se você usar a WindowHelper classe.)

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();
}

Quando o destaque de guias começa, uma nova janela é solicitada. Aqui, a variável tabTearOutWindow fornece acesso à nova janela depois de criada. Os métodos auxiliares CreateWindow e TrackWindow criam uma nova janela e a adicionam à lista de rastreamento de janela ativa.

Depois de criar a nova janela, você precisará criar uma nova Página e defini-la como o conteúdo da janela. A nova Página deve conter um controle TabView para o qual você moverá a guia destacada no manipulador de eventos TabTearOutRequested.

Dica

Neste exemplo, criamos uma nova MainPage classe, pois ela contém apenas um TabView vazio (nenhuma guia é adicionada diretamente no XAML). Se MainPage incluir outros elementos de interface do usuário que não devem aparecer na janela rasgada, você poderá criar uma página separada que inclua apenas os elementos necessários (incluindo pelo menos um TabView) e criar uma instância dessa página.

Por fim, atribua o AppWindow.Id da nova janela à args. propriedade NewWindowId. Isso será usado na propriedade TabViewTabTearOutRequestedEventArgs.NewWindowId para que você possa acessar a janela desse manipulador de eventos.

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);
}

Fechar uma janela quando a última guia é fechada

Conforme mencionado anteriormente, talvez você queira fechar a janela quando a última guia em um TabView estiver fechada. Se seu aplicativo tiver várias janelas, você precisará encontrar a janela correta para fechar em sua lista de janelas controladas. Este exemplo mostra como fazer isso.

// 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;
}

Mover a guia para a nova janela

Depois que a nova janela tiver sido fornecida, você precisará remover a guia rasgada do sender TabView e adicioná-la ao TabView na nova janela. Neste exemplo, o método auxiliar public AddTabToTabs permite que você acesse TabView na nova instância MainPage da instância de página original para adicionar a guia destacada a ela.

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);
}

Arrastar uma guia destacada para outro TabView

Quando uma guia foi destacada e colocada em uma nova janela, conforme mostrado nas etapas anteriores, uma dessas duas coisas pode acontecer:

  • O usuário pode soltar a guia e permanecer na nova janela. O processo de destaque termina aqui e não há mais eventos gerados.
  • O usuário pode continuar a arrastar a guia destacada de volta para um controle TabView existente. Nesse caso, o processo continua e vários outros eventos são gerados para permitir que você remova a guia do TabView original e insira a guia externa em um TabView existente.

Quando a guia é arrastada sobre o TabView existente, o evento ExternalTornOutTabsDropping é acionado. No manipulador de eventos, você pode determinar se a inserção da aba neste TabView é permitida. Na maioria dos casos, você só precisa definir a args. propriedade AllowDrop como true. No entanto, se você precisar executar quaisquer verificações antes de definir essa propriedade, poderá fazer isso aqui. Se AllowDrop estiver definido como false, a ação de arrastar de guia continuará e o evento ExternalTornOutTabsDropped não será acionado.

private void TabView_ExternalTornOutTabsDropping(TabView sender, 
                        TabViewExternalTornOutTabsDroppingEventArgs args)
{
    args.AllowDrop = true;
}

Se AllowDrop estiver definido como true no ExternalTornOutTabsDropping manipulador de eventos, o ExternalTornOutTabsDropped evento será gerado imediatamente.

Observação

O Dropped no nome do evento não corresponde diretamente à ideia de uma ação de soltar nas APIs do tipo "arrastar e soltar". Aqui, o usuário não precisa liberar a guia para executar uma ação de soltar. O evento é gerado enquanto a guia é mantida sobre a faixa de guias e o código é executado para soltar a guia no TabView.

O evento ExternalTornOutTabsDropped segue o mesmo padrão do evento TabTearOutRequested, porém de forma invertida; você precisa remover a aba do TabView de origem e inseri-la no sender TabView.

O sender TabView é o controle no qual a guia está sendo inserida, portanto, usamos o GetParentTabView método auxiliar para localizar a guia de origem. Ele começa com o TabViewItem rasgado e usa o VisualTreeHelper para percorrer a árvore visual e encontrar o TabView ao qual o item pertence. Depois que o TabView é encontrado, o TabViewItem é removido de sua coleção TabItems e inserido na coleção do sender TabView TabItems no índice especificado pelo 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;
}

Dica

Se você estiver usando o Kit de Ferramentas da Comunidade do Windows, poderá usar o método auxiliar FindAscendant nas DependencyObjectExtensions do kit de ferramentas em vez de GetParentTabView.

Exibir as guias TabView na barra de título de uma janela

Em vez de ter guias ocupando sua própria linha abaixo da barra de título de uma janela de aplicativo, você pode mesclar as duas na mesma área. Isso economiza espaço vertical do seu conteúdo e confere ao seu aplicativo uma sensação moderna.

Como um usuário pode arrastar uma janela pela barra de título para reposicionar a Janela, é importante que a barra de título não esteja completamente cheia de guias. Portanto, ao exibir guias em uma barra de título, você deve especificar uma parte da barra de título a ser reservada como uma área arrastável. Se você não especificar uma região arrastável, toda a barra de título será arrastável, o que impede que suas guias recebam eventos de entrada. Se o TabView for exibido na barra de título de uma janela, você sempre deverá incluir um TabStripFooter em seu TabView e marcá-lo como uma região arrastável.

Para obter mais informações, confira Personalização da barra de título

Guias na barra de título

<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;
}

Observação

Como você obtém uma referência à janela pode variar dependendo de como você rastreia janelas em seu aplicativo. Para obter mais informações, consulte Fechar a janela quando a última guia estiver fechada e Criar e acompanhar uma nova janela neste artigo.

Diretrizes de teclado para desenvolvedores

Dica

Para obter mais informações sobre o suporte interno ao teclado, consulte a navegação por teclado anteriormente neste artigo.

Alguns aplicativos podem exigir um controle de teclado mais avançado. Considere implementar os seguintes atalhos se eles forem apropriados para seu aplicativo.

Aviso

Se estiver adicionando um TabView a um aplicativo existente, você já poderá ter criado atalhos de teclado mapeados para as combinações de teclas dos atalhos de teclado TabView recomendados. Nesse caso, você precisará considerar se deseja manter seus atalhos existentes ou oferecer uma experiência de guia intuitiva para o usuário.

  • Ctrl + T deve abrir uma nova guia. Geralmente, essa guia é preenchida com um documento predefinido ou é criada vazia com uma maneira simples de escolher seu conteúdo. Se o usuário precisar escolher o conteúdo para uma nova guia, considere fornecer o foco de entrada para o controle de seleção de conteúdo.
  • Ctrl + W deve fechar a guia selecionada. Lembre-se de que TabView selecionará a próxima guia automaticamente.
  • Ctrl + Shift + T deve abrir guias fechadas recentemente (ou, mais precisamente, abrir novas guias com o mesmo conteúdo que as guias fechadas recentemente). Comece com a guia fechada mais recentemente e mova-se para trás no tempo para cada vez anterior em que o atalho foi invocado. Observe que isso exigirá a manutenção de uma lista de guias fechadas recentemente.
  • Ctrl + 1 deve selecionar a primeira guia na lista de guias. Da mesma forma, Ctrl + 2 deve selecionar a segunda guia, Ctrl + 3 deve selecionar a terceira e assim por diante até Ctrl + 8.
  • Ctrl + 9 deve selecionar a última guia na lista de guias, independentemente de quantas guias estão na lista.
  • Se as guias oferecerem mais do que apenas o comando fechar (como duplicar ou fixar uma guia), use um menu de contexto para mostrar todas as ações disponíveis que podem ser executadas em uma guia.

Implementar comportamento de teclado do estilo do navegador

Esse exemplo implementa várias das recomendações acima em um TabView. Especificamente, este exemplo implementa Ctrl + T, Ctrl + W, Ctrl + 1-8 e 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 e WinUI 2

Importante

As informações e exemplos neste artigo são otimizados para aplicativos que usam o SDK do Aplicativo Windows e o WinUI 3, mas geralmente são aplicáveis a aplicativos UWP que usam o WinUI 2. Consulte a referência da API UWP para obter informações e exemplos específicos da plataforma.

Esta seção contém informações necessárias para usar o controle em um aplicativo UWP ou WinUI 2.

O controle TabView para aplicativos UWP é incluído como parte do WinUI 2. Para obter mais informações, incluindo instruções de instalação, consulte WinUI 2. As APIs para esse controle existem no namespace Microsoft.UI.Xaml.Controls .

As APIs de destaque de guias não estão incluídas na versão WinUI 2 de TabView.

Recomendamos usar a versão mais recente do WinUI 2 () para obter os estilos, modelos e recursos mais atualizados para todos os controles. WinUI 2.2 ou posterior inclui um novo modelo para esse controle que usa cantos arredondados. Para obter mais informações, consulte raio de canto .

Para usar o código neste artigo com a WinUI 2, use um alias em XAML (usamos muxc) para representar as APIs da Biblioteca de Interface do Usuário do Windows incluídas em seu projeto. Confira Introdução ao WinUI 2 para obter mais informações.

xmlns:muxc="using:Microsoft.UI.Xaml.Controls"

<muxc:TabView />