Compartir a través de


Vista de pestañas

El control TabView es una manera de mostrar un conjunto de pestañas y su contenido correspondiente. Los controles TabView son útiles para mostrar varias páginas (o documentos) del contenido, al tiempo que permiten al usuario reorganizar, cerrar o abrir nuevas pestañas.

Ejemplo de un TabView

¿Es este el control adecuado?

En general, las interfaces de usuario con pestañas vienen en uno de los dos estilos distintos que difieren en función y apariencia:

  • Las pestañas estáticas son el tipo de pestañas que a menudo se encuentran en las ventanas de configuración. Contienen un número establecido de páginas en un orden fijo que normalmente incluyen contenido predefinido.
  • Las pestañas de documento son el tipo de pestañas que se encuentran en un explorador, como Microsoft Edge. Los usuarios pueden crear, quitar y reorganizar las pestañas, desplazar las pestañas entre ventanas y cambiar el contenido de las pestañas.

De forma predeterminada, TabView está configurado para proporcionar pestañas de documento. Se recomienda TabView cuando los usuarios puedan:

  • Abrir, cerrar o reorganizar pestañas dinámicamente.
  • Abra documentos o páginas web directamente en pestañas.
  • Arrastre y coloque pestañas entre ventanas.

La API TabView permite configurar el control para las pestañas estáticas. Sin embargo, para seguir las instrucciones de diseño de Windows y si hay más de algunos elementos de navegación estáticos, considere la posibilidad de usar un control NavigationView .

Anatomía

La interfaz de usuario con pestañas se crea con un control TabView y uno o varios controles TabViewItem. TabView hospeda instancias de TabViewItem, que representa una sola pestaña y su contenido.

Elementos TabView

Esta imagen muestra las partes del control TabView . La franja de pestañas tiene un encabezado y pie de página, pero a diferencia de un documento, el encabezado y el pie de página de la franja de pestañas se encuentran en el extremo izquierdo y el extremo derecho de la franja, respectivamente.

Esta imagen muestra las partes del control de vista de pestañas. La franja de pestañas contiene cuatro pestañas y tiene un encabezado y pie de página, que se encuentran en el extremo izquierdo y el extremo derecho de la franja, respectivamente.

Elementos de TabViewItem

Esta imagen muestra las partes del control TabViewItem . Aunque el contenido se muestra dentro del control TabView, el contenido es realmente una parte del objeto TabViewItem.

Esta imagen muestra las partes del control de elemento de vista de pestaña. Se selecciona una pestaña individual, que tiene un icono y una etiqueta, con un área de contenido debajo de la pestaña.

Recommendations

Selección de pestañas

La mayoría de los usuarios tiene experiencia en el uso de pestañas de documentos simplemente por el hecho de usar un explorador web. Cuando usen pestañas de documentos en tu aplicación, su experiencia condiciona sus expectativas acerca de cómo deben comportarse las pestañas.

Independientemente de cómo interactúe el usuario con un conjunto de pestañas de documento, siempre debe haber una pestaña activa. Si el usuario cierra la pestaña seleccionada o divide la pestaña seleccionada en otra ventana, otra pestaña debe convertirse en la pestaña activa. TabView intenta hacerlo automáticamente seleccionando la pestaña siguiente. Si tienes una buena razón por la que tu aplicación debe permitir una tabView con una pestaña no seleccionada, el área de contenido de TabView simplemente estará en blanco.

Navegación por teclado

TabView admite muchos escenarios comunes de navegación por teclado de forma predeterminada. En esta sección se explica la funcionalidad integrada y se hacen recomendaciones sobre funcionalidades adicionales que pueden resultar útiles para algunas aplicaciones.

Comportamiento de las teclas de tabulación y de cursor

Cuando el foco se mueve al área tabStrip de , el TabViewItem seleccionado obtiene el foco. A continuación, el usuario puede usar las teclas de dirección Izquierda y Derecha para mover el foco (no la selección) a otras pestañas de la franja de pestañas. El foco de las flechas queda atrapado en la franja de pestañas y el botón de agregar pestaña (+), si hay uno. Para alejar el foco del área de la franja de pestañas, el usuario puede presionar la tecla Tab , que moverá el foco al siguiente elemento enfocado.

Desplazar el foco mediante Tabulador

Mover el foco mediante la tecla Tab

Las teclas de flecha no reinician el ciclo del foco

Las teclas de flecha no reinician el ciclo del foco

Seleccionar una pestaña

Cuando un TabViewItem tiene el foco, presione Espacio o Entrar para seleccionar ese TabViewItem.

Use las teclas de dirección para mover el foco y, a continuación, presione Espacio para seleccionar la pestaña.

Espacio para seleccionar la pestaña

Accesos directos para seleccionar pestañas adyacentes

Presione Ctrl+Tab para seleccionar el siguiente TabViewItem. Presione Ctrl+Mayús+Tab para seleccionar el elemento TabViewItem anterior. Para estos fines, la lista de pestañas está "en bucle", por lo que seleccionar la pestaña siguiente mientras se selecciona la última pestaña hará que se seleccione la primera pestaña.

Cerrar una pestaña

Presione Ctrl + F4 para generar el evento TabCloseRequested . Controla dicho evento y cierra la pestaña si es necesario.

Sugerencia

Para obtener más información, consulte Instrucciones de teclado para desarrolladores más adelante en este artículo.

Crear una vista de pestañas

La aplicación WinUI 3 Gallery incluye ejemplos interactivos de la mayoría de los controles, características y funcionalidades de WinUI 3. Obtén la aplicación desde la Microsoft Store o consigue el código fuente en GitHub

Los ejemplos de esta sección muestran una variedad de formas de configurar un control TabView .

Elementos de la vista de pestañas

Cada pestaña de un control TabView se representa mediante un control TabViewItem , que incluye la pestaña que se muestra en la franja de pestañas y el contenido que se muestra debajo de la franja de pestañas.

Configurar una pestaña

Para cada TabViewItem, puede establecer un encabezado y un icono y especificar si el usuario puede cerrar la pestaña.

  • La propiedad Header se establece normalmente en un valor de cadena que proporciona una etiqueta descriptiva para la pestaña. Sin embargo, la Header propiedad puede ser cualquier objeto. También puede usar la propiedad HeaderTemplate para especificar un DataTemplate que defina cómo se deben mostrar los datos de encabezado enlazados.
  • Establezca la propiedad IconSource para especificar un icono para la pestaña.
  • De forma predeterminada, la pestaña muestra un botón cerrar (X). Puede establecer la propiedad IsClosable en false para ocultar el botón cerrar y asegurarse de que un usuario no puede cerrar la pestaña. (Si cierra las pestañas en el código de la aplicación fuera de un evento solicitado de cierre , primero debe comprobar que IsClosable es true).

Para TabView, puede configurar varias opciones que se aplican a todas las pestañas.

  • De forma predeterminada, el botón Cerrar siempre se muestra para las pestañas que se pueden ocultar. Puede establecer la propiedad CloseButtonOverlayMode en OnPointerOver para cambiar este comportamiento. En este caso, la pestaña seleccionada siempre muestra el botón Cerrar si es closable, pero las pestañas no seleccionadas muestran el botón cerrar solo cuando la pestaña es closable y el usuario tiene su puntero sobre él.
  • Puede establecer la propiedad TabWidthMode para cambiar el tamaño de las pestañas. (La Width propiedad se omite en TabViewItem). Estas son las opciones de la enumeración TabViewWidthMode :
    • Equal - Cada pestaña tiene el mismo ancho. Este es el valor predeterminado.
    • SizeToContent - Cada pestaña ajusta su ancho al contenido dentro de la pestaña.
    • Compact - Las pestañas no seleccionadas se contraen para mostrar solo su icono. La pestaña seleccionada se ajusta para mostrar el contenido dentro de la pestaña.

Content

Los elementos que se muestran en la pestaña seleccionada se agregan a la propiedad Content del objeto TabViewItem. TabViewItem es un ContentControl, por lo que puede agregar cualquier tipo de objeto como contenido. También puede aplicar un DataTemplate a la propiedad ContentTemplate. Consulte la clase ContentControl para obtener más información.

Los ejemplos de este artículo muestran un caso sencillo de agregar texto directamente al Content elemento en XAML. Sin embargo, la interfaz de usuario real suele ser más compleja. Una manera común de agregar una interfaz de usuario compleja como el contenido de una pestaña es encapsularlo en un UserControl o en una página, y agregarlo como el contenido del objeto TabViewItem. En este ejemplo se supone que la aplicación tiene un UserControl XAML denominado PictureSettingsControl.

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

Pestañas estáticas

En este ejemplo se muestra un TabView simple con dos pestañas estáticas. Ambos elementos de pestaña se agregan en XAML como contenido de TabView.

Para que un control TabView sea estático, use estas configuraciones:

  • Establezca la propiedad IsAddTabButtonVisible en false para ocultar el botón agregar pestaña e impedir que se genere el evento AddTabButtonClick .
  • Establezca la propiedad CanReorderTabs en false para evitar que el usuario arrastre pestañas a un orden diferente.
  • En cada TabViewItem, establezca la propiedad IsClosable en false para ocultar el botón de cerrar pestaña e impedir que el usuario genere el evento 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>

Pestañas del documento

De forma predeterminada, TabView está configurado para las pestañas del documento. El usuario puede agregar nuevas pestañas, reorganizar pestañas y cerrar pestañas. En esta configuración, debe controlar los eventos AddTabButtonClick y TabCloseRequested para habilitar la funcionalidad.

Cuando se agregan pestañas a un TabView, es posible que finalmente haya demasiadas pestañas para mostrar en la barra de pestañas. En este caso, aparecerán los indicadores de desplazamiento que permiten desplazarse hacia la izquierda y hacia la derecha para acceder a las pestañas ocultas.

En este ejemplo se crea un tabView de simple junto con controladores de eventos para admitir pestañas de apertura y cierre. El TabView_AddTabButtonClick controlador de eventos muestra cómo agregar un tabViewItem en el 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);
}

Cierre la ventana cuando se cierre la última pestaña.

Si todas las pestañas de la aplicación se pueden cerrar y la ventana de la aplicación debe cerrarse cuando se cierre la última pestaña, también debe cerrar la ventana en el controlador de eventos TabCloseRequested .

En primer lugar, en el archivo App.xaml.cs, agregue una propiedad public static que le permita acceder a la instancia Window desde el Page que hospeda el TabView. (Consulte Seguimiento de la ventana actual en Información general sobre ventanas).

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

A continuación, modifique el controlador de eventos TabCloseRequested para llamar a Window.Close si se han quitado todas las pestañas de 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();
    }
}

Nota:

Este ejemplo funciona para una aplicación con una sola ventana (MainWindow). Si la aplicación tiene varias ventanas o ha habilitado la eliminación de pestañas, debe realizar un seguimiento de las ventanas y, a continuación, buscar la correcta para cerrarla. Consulte la sección siguiente para obtener un ejemplo de esto.

Desmontaje de tabulación

El desprendimiento de pestaña describe lo que sucede cuando un usuario arrastra una pestaña fuera de la barra de pestañas de TabView y la mueve a otro control TabView, generalmente en una nueva ventana.

A partir de Windows App SDK 1.6, TabView tiene una propiedad CanTearOutTabs que puede establecer para proporcionar una experiencia mejorada para arrastrar pestañas a una nueva ventana. Cuando un usuario arrastra una pestaña fuera de la franja de pestañas con esta opción está habilitada, se crea inmediatamente una nueva ventana durante el arrastre, lo que permite al usuario arrastrarlo al borde de la pantalla para maximizar o ajustar la ventana en un movimiento suave. Esta implementación tampoco utiliza las API de arrastrar y soltar, por lo que no se ve afectada por las limitaciones de dichas API.

Cuando establece la propiedad CanTearOutTabs en true, hace que se generen los eventos de desmontaje de tabulación en lugar de los eventos de arrastrar y colocar. Para implementar el desmontaje de tabulación, debe controlar estos eventos:

  • TabTearOutWindowRequested

    Este evento se produce cuando una pestaña se arrastra por primera vez fuera de la barra de pestañas. Contrólelo para crear una nueva ventana y TabView a la que se moverá la pestaña.

  • TabTearOutRequested

    Este evento se produce después de proporcionar una nueva ventana. Contrólelo para mover la pestaña desmontada de la TabView de origen a una TabView en la nueva ventana.

  • ExternalTornOutTabsDropping

    Este evento se produce cuando se arrastra una pestaña desmontada sobre un control TabView existente. Contrólelo en la TabView que recibe la pestaña desmontada para indicar si se debe aceptar o no la pestaña.

  • ExternalTornOutTabsDrop

    Este evento se produce cuando se arrastra una pestaña desmontada sobre una TabView existente y el evento ExternalTornOutTabsDropping indica que se permite la colocación. Contrólelo en la TabView que recibe la pestaña desmontada para quitar la pestaña de la TabView de origen e insertarla en la TabView receptora en el índice especificado.

Estos eventos no se generan cuando la separación de pestañas está habilitada: TabDragStarting, TabStripDragOver, TabStripDrop, TabDragCompleted, TabDroppedOutside.

Precaución

El desmontaje de tabulación se admite en los procesos que se ejecutan con privilegios elevados como administrador.

En los ejemplos siguientes se muestra cómo implementar los controladores de eventos para admitir el desmontaje de pestañas.

Configuración de TabView

Este XAML establece la propiedad CanTearOutTabs en true, y configura los controladores de eventos de desmontaje de pestañas.

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

Creación y seguimiento de una nueva ventana

El desmontaje de pestañas requiere que cree y administre nuevas ventanas en la aplicación.

Sugerencia

La aplicación Galería de WinUI incluye una WindowHelper clase que facilita la administración de ventanas en la aplicación. Puede copiarlo desde GitHub en el repositorio de la Galería de WinUI: WindowHelper.cs. Se recomienda esta clase auxiliar para implementar el desmontaje de pestañas. Consulte TabViewWindowingSamplePage en GitHub para ver cómo se usa.

En este artículo, los métodos auxiliares se copian de WindowHelper.cs, pero se modifican y se muestran en línea para mejorar la legibilidad.

Aquí se crea una lista para realizar un seguimiento de todas las ventanas activas en App.xaml.cs. El OnLaunched método se actualiza para realizar un seguimiento de la ventana después de crearlo. (Esto no es necesario si usa la WindowHelper clase ).

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

Cuando comienza el desmontaje de pestañas, se solicita una nueva ventana. Aquí, la variable tabTearOutWindow proporciona acceso a la nueva ventana después de crearla. Los CreateWindow métodos auxiliares y TrackWindow crean una nueva ventana y la agregan a la lista de seguimiento de ventanas activa.

Después de crear la nueva ventana, debe crear una nueva página y establecerla como el contenido de la ventana. La nueva página debe contener un control TabView en el que se moverá la pestaña desmontada en el controlador de eventos TabTearOutRequested.

Sugerencia

En este ejemplo, creamos una nueva MainPage clase, ya que solo contiene un control TabView vacío (no se agregan pestañas directamente en XAML). Si MainPage incluye otros elementos de la interfaz de usuario que no deben aparecer en la ventana rasgada, puede crear una página independiente que incluya solo los elementos que necesite (incluido al menos un Control TabView) y crear una instancia de esa página.

Por último, asigne el AppWindow.Id de la nueva ventana a la args. propiedad NewWindowId. Esto se usará en la propiedad TabViewTabTearOutRequestedEventArgs.NewWindowId para que pueda acceder a la ventana desde ese controlador 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);
}

Cierre una ventana cuando se cierre la última pestaña

Como se mencionó anteriormente, quizás desee cerrar la ventana cuando se cierre la última pestaña en un TabView. Si la aplicación tiene varias ventanas, debe encontrar la ventana correcta para cerrarla en la lista de ventanas con seguimiento. En este ejemplo se muestra cómo hacerlo.

// 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 la pestaña a la nueva ventana

Una vez proporcionada la nueva ventana, debe quitar la pestaña desmontada de la TabView sender y agregarla a la TabView en la nueva ventana. En este ejemplo, el método auxiliar public AddTabToTabs te permite acceder a TabView en la nueva instancia MainPage desde la instancia de página original para añadir la pestaña extraída.

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

Arrastre una pestaña desmontada a otra TabView

Cuando se ha desgarrado una pestaña y se ha colocado en una nueva ventana, como se muestra en los pasos anteriores, puede ocurrir una de estas dos cosas:

  • El usuario puede quitar la pestaña y permanece en la nueva ventana. El proceso de desmontaje finaliza aquí y no se generan más eventos.
  • El usuario puede seguir arrastrando la pestaña desmontada a un control TabView existente. En este caso, el proceso continúa y se generan varios eventos más para permitirle quitar la pestaña del TabView original e insertar la pestaña externa en un TabView existente.

Cuando la pestaña se arrastra sobre el control TabView existente, se activa el evento ExternalTornOutTabsDropping. En el controlador de eventos, puede determinar si está permitida la inserción de la pestaña en este TabView. En la mayoría de los casos, solo tiene que establecer la propiedad args.AllowDrop en true. Sin embargo, si necesita realizar comprobaciones antes de establecer esa propiedad, puede hacerlo aquí. Si AllowDrop se establece en false, la acción de arrastrar la pestaña continúa y no se genera el evento ExternalTornOutTabsDropped.

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

Si AllowDrop se establece a true en el controlador de eventos ExternalTornOutTabsDropping, el evento ExternalTornOutTabsDropped se genera inmediatamente.

Nota:

El Dropped en el nombre del evento no se corresponde directamente con la idea de una acción de colocación en las API de arrastrar y colocar. Aquí, el usuario no necesita liberar la pestaña para realizar una acción de colocación. El evento se genera mientras la pestaña se mantiene sobre la franja de pestañas y el código se ejecuta para colocar la pestaña en tabView.

El controlador de eventos ExternalTornOutTabsDropped sigue el mismo patrón que el evento TabTearOutRequested, pero invertido; debe quitar la pestaña de la TabView de origen e insertarla en la TabView sender.

TabView sender es el control en el que se inserta la pestaña, por lo que usamos el GetParentTabView método auxiliar para buscar la pestaña de origen. Comienza con el TabViewItem rasgado y usa VisualTreeHelper para recorrer el árbol visual y encontrar el control TabView al que pertenece el elemento. Una vez que se encuentra TabView, TabViewItem se elimina de su colección TabItems y se inserta en la colección sender de TabView TabItems en el índice especificado por 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;
}

Sugerencia

Si usa el Kit de herramientas de la comunidad Windows, puede usar el método auxiliar FindAscendant en DependencyObjectExtensions del kit de herramientas en lugar de GetParentTabView.

Mostrar pestañas TabView en la barra de título de una ventana

En lugar de que las pestañas ocupen su propia fila debajo de la barra de título de una ventana, puede combinar las dos en el mismo área. De este modo, se ahorra espacio vertical para el contenido y la aplicación adquiere un aspecto más moderno.

Dado que un usuario puede arrastrar una ventana por su barra de título para cambiar la posición de la ventana, es importante que la barra de título no esté completamente llena de pestañas. Por lo tanto, al mostrar pestañas en una barra de título, debe especificar una parte de la barra de título que se va a reservar como un área arrastrable. Si no especifica una región arrastrable, se podrá arrastrar toda la barra de título, lo que impide que las pestañas reciban eventos de entrada. Si su TabView se mostrará en la barra de título de una ventana, siempre debe incluir un TabStripFooter en tabView y marcarlo como una región arrastrable.

Para obtener más información, consulte Personalización de la barra de título.

Pestañas en la 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;
}

Nota:

La forma de obtener una referencia a la ventana puede variar en función de cómo realice el seguimiento de las ventanas en la aplicación. Para obtener más información, vea Cerrar la ventana cuando se cierra la última pestaña y Crear y realizar un seguimiento de una nueva ventana de este artículo.

Instrucciones de teclado para desarrolladores

Sugerencia

Para obtener más información sobre la compatibilidad con teclado integrada, consulte Navegación por teclado anteriormente en este artículo.

Algunas aplicaciones pueden requerir un control de teclado más avanzado. Ten en cuenta la posibilidad de implementar los siguientes accesos directos si son adecuados para tu aplicación.

Advertencia

Si va a agregar un TabView a una aplicación existente, es posible que ya haya creado métodos abreviados de teclado que se asignen a las combinaciones de teclas de los métodos abreviados de teclado tabView recomendados. En este caso, tendrás que decidir si quieres mantener los accesos directos existentes u ofrecer al usuario una experiencia de pestañas intuitiva.

  • Ctrl + T debe abrir una nueva pestaña. Por lo general, esta pestaña se rellena con un documento predefinido o se crea vacía con una manera sencilla de elegir su contenido. Si el usuario debe elegir contenido para una nueva pestaña, ten en cuenta la posibilidad de poner el foco de entrada en el control de selección de contenido.
  • Ctrl + W debe cerrar la pestaña seleccionada. Recuerde que TabView seleccionará automáticamente la pestaña siguiente.
  • Ctrl + Mayús + T debe abrir pestañas cerradas recientemente (o más precisamente, abrir nuevas pestañas con el mismo contenido que las pestañas cerradas recientemente). Comienza con la pestaña cerrada más recientemente y retrocede en el tiempo para cada vez que se invoque al método abreviado. Ten en cuenta que esto exigirá mantener una lista de pestañas cerradas recientemente.
  • Ctrl + 1 debe seleccionar la primera pestaña de la lista de pestañas. Del mismo modo, con Control + 2 se debe seleccionar la segunda pestaña, con Control + 3, la tercera y así sucesivamente hasta Control + 8.
  • Ctrl + 9 debe seleccionar la última pestaña de la lista de pestañas, independientemente del número de pestañas de la lista.
  • Si las pestañas ofrecen más que simplemente el comando cerrar (como la duplicación o el anclaje de una pestaña), usa un menú contextual para mostrar todas las acciones disponibles que se pueden realizar en una pestaña.

Implementar un comportamiento de teclado al estilo del explorador

En este ejemplo se implementan varias de las recomendaciones anteriores en un TabView. En concreto, este ejemplo implementa Ctrl + T, Ctrl + W, Ctrl + 1-8 y 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 y WinUI 2

Importante

La información y los ejemplos de este artículo están optimizados para aplicaciones que usan el SDK de Aplicaciones para Windows y WinUI 3, pero generalmente son aplicables a las aplicaciones para UWP que usan WinUI 2. Consulta la referencia de la API de UWP para obtener información y ejemplos específicos de la plataforma.

Esta sección contiene la información que necesitas para utilizar el control en una aplicación UWP o WinUI 2.

El control TabView para aplicaciones para UWP se incluye como parte de WinUI 2. Para obtener más información, incluidas las instrucciones de instalación, consulta WinUI 2. Existen API para este control en el espacio de nombres Microsoft.UI.Xaml.Controls .

Las API de desmontaje de pestañas no se incluyen en la versión WinUI 2 de TabView.

Se recomienda usar la versión más reciente de WinUI 2 para obtener los estilos, plantillas y características más actuales para todos los controles. WinUI 2.2 o posterior incluye una nueva plantilla para este control que usa esquinas redondeadas. Para obtener más información, consulta Radio de redondeo.

Para usar el código de este artículo con WinUI 2, use un alias en XAML (usamos muxc) para representar las API de la biblioteca de interfaz de usuario de Windows que se incluyen en el proyecto. Consulta Introducción a WinUI 2 para obtener más información.

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

<muxc:TabView />