This article has been localized into Spanish by the community.
Usando el control TabControl de WPF
El control TabControl de WPF te permite distribuir tu interfaz en diferentes áreas, cada una de ellas accesibles haciendo clic en la pestaña de la cabecera, usualmente situada en la parte superior del control. Los controles de pestañas generalmente son usados en las aplicaciones de Windows e incluso en las propias interfaces de Windows, así como el cuadro de diálogo de propiedades de archivos/carpetas, etc.
Como en el caso de la mayoría de controles WPF, es muy fácil empezar a usar el TabControl. Aquí tienes un ejemplo muy básico:
<Window x:Class="WpfTutorialSamples.Misc_controls.TabControlSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TabControlSample" Height="200" Width="250">
<Grid>
<TabControl>
<TabItem Header="General">
<Label Content="Content goes here..." />
</TabItem>
<TabItem Header="Security" />
<TabItem Header="Details" />
</TabControl>
</Grid>
</Window>
Como puedes comprobar, cada pestaña es representada con el elemento TabItem, donde el texto mostrado es controlado por la propiedad Header. El elemento TabItem viene de la clase ContentControl, lo que significa que tu puedes definir un único elemento en el interior del mismo que será mostrado si la pestaña está activa (como en la figura del ejemplo). He usado un elemento Label en este ejemplo, pero si quieres ubicar más de un control dentro de la pestaña, utiliza uno de los paneles con los controles anidados dentro de él.
Encabezados Personalizados
Una vez más, WPF prueba ser extremadamente flexible cuando usted quiere personalizar la apariencia de sus pestañas. Obviamente el contenido puede ser representado de la forma que quiera, ¡pero también los encabezados de las pestañas! La propiedad Header (Encabezado), puede ser llenada con cualquier cosa que usted quiera, aprovecharemos esto en el siguiente ejemplo:
<Window x:Class="WpfTutorialSamples.Misc_controls.TabControlWithCustomHeadersSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TabControlWithCustomHeadersSample" Height="200" Width="250">
<Grid>
<Grid>
<TabControl>
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="/WpfTutorialSamples;component/Images/bullet_blue.png" />
<TextBlock Text="Blue" Foreground="Blue" />
</StackPanel>
</TabItem.Header>
<Label Content="Content goes here..." />
</TabItem>
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="/WpfTutorialSamples;component/Images/bullet_red.png" />
<TextBlock Text="Red" Foreground="Red" />
</StackPanel>
</TabItem.Header>
</TabItem>
<TabItem>
<TabItem.Header>
<StackPanel Orientation="Horizontal">
<Image Source="/WpfTutorialSamples;component/Images/bullet_green.png" />
<TextBlock Text="Green" Foreground="Green" />
</StackPanel>
</TabItem.Header>
</TabItem>
</TabControl>
</Grid>
</Grid>
</Window>
La cantidad de etiquetas puede ser un poco abrumadora, pero como probablemente podrá ver una vez que ahonde en ello, todo es muy simple. Cada una de las pestañas ahora tiene un elemento TabItem.Header, que contiene un StackPanel, que a su vez contiene una imagen y un control TextBlock. Esto nos permite tener una imagen en cada una de las pestañas y personalizar el color del texto (también podríamos haberlo escrito en negritas, itálicas u otro tamaño).
Controlando el TabControl
A veces puedes querer controlar, mediante código, cuál panel está seleccionado o quizás obtener alguna información acerca de la pestaña seleccionada. El control TabControl de WPF tiene algunas propiedades que hacen esto posible, incluyendo SelectedIndex y SelectedItem. En el próximo ejemplo, he agregado un par de botones al primer ejemplo que nos permiten controlar el TabControl:
<Window x:Class="WpfTutorialSamples.Misc_controls.ControllingTheTabControlSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ControllingTheTabControlSample" Height="300" Width="350">
<DockPanel>
<StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" Margin="2,5">
<Button Name="btnPreviousTab" Click="btnPreviousTab_Click">Prev.</Button>
<Button Name="btnNextTab" Click="btnNextTab_Click">Next</Button>
<Button Name="btnSelectedTab" Click="btnSelectedTab_Click">Selected</Button>
</StackPanel>
<TabControl Name="tcSample">
<TabItem Header="General">
<Label Content="Content goes here..." />
</TabItem>
<TabItem Header="Security" />
<TabItem Header="Details" />
</TabControl>
</DockPanel>
</Window>
using System;
using System.Windows;
using System.Windows.Controls;
namespace WpfTutorialSamples.Misc_controls
{
public partial class ControllingTheTabControlSample : Window
{
public ControllingTheTabControlSample()
{
InitializeComponent();
}
private void btnPreviousTab_Click(object sender, RoutedEventArgs e)
{
int newIndex = tcSample.SelectedIndex - 1;
if(newIndex < 0)
newIndex = tcSample.Items.Count - 1;
tcSample.SelectedIndex = newIndex;
}
private void btnNextTab_Click(object sender, RoutedEventArgs e)
{
int newIndex = tcSample.SelectedIndex + 1;
if(newIndex >= tcSample.Items.Count)
newIndex = 0;
tcSample.SelectedIndex = newIndex;
}
private void btnSelectedTab_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Selected tab: " + (tcSample.SelectedItem as TabItem).Header);
}
}
}
Como acabas de ver, simplemente he adicionado un juego de botones en la parte inferior de la interface. Los primeros dos permiten seleccionar la anterior o la siguiente pestaña en el control, mientras que el último mustra la información acerca de la pestaña actualmente seleccionada, como se muestra en la captura de pantalla
Los primeros dos botones usan la propiedad SelectedIndexpara determinar en cuál pestaña estamos y entonces, restar o sumar uno a ese valor, asegurando que el nuevo índice no esté por encima o por debajo de la cantidad de pestañas disponibles. El tercer botón usa la propiedad SelectedItem para obtener una referencia a la pestaña seleccionada. Como puedes ver, tengo que forzar que el tipo sea de la clase TabItem para obtener el valor de la propiedad Header, ya que de manera predeterminada, SelectedItem es del tipo Object.
Resumen
El control TabControl es estupendo cuando necesitas una separación clara en un diálogo o cuando simplemente no hay suficiente espacio para todos los controles que quieres adentro de él. En los próximos dos capítulos, veremos algunas de las posibilidades que hay cuando se usa el TabControl para varios propósitos.