TOC

This article is currently in the process of being translated into Spanish (~99% done).

Controles de lista:

The ComboBox control

El control ComboBox es parecido al control ListBox en muchos sentidos, pero usa mucho menos espacio, ya que la lista de ítems se encuentra oculta cuando no se necesita. El control ComboBox es usado en muchos lugares dentro de Windows, pero para asegurarnos que todos saben cómo luce y cómo opera, pasemos al siguiente ejemplo:

<Window x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ComboBoxSample" Height="150" Width="200">
    <StackPanel Margin="10">
        <ComboBox>
            <ComboBoxItem>ComboBox Item #1</ComboBoxItem>
            <ComboBoxItem IsSelected="True">ComboBox Item #2</ComboBoxItem>
            <ComboBoxItem>ComboBox Item #3</ComboBoxItem>
        </ComboBox>
    </StackPanel>
</Window>

En la captura de pantalla se encuentra activado el control al haberle hecho clic, lo que ocasiona que despliegue la lista de ítems. Como se puede ver en el código, el ComboBox, en su forma simple es muy fácil de usar. Lo que voy a hacer es agregar algunos ítems en forma manual haciendo que uno de ellos sea la opción seleccionada por defecto poniéndole la propiedad IsSelected.

Contenido personalizado

En el primer ejemplo sólo mostramos texto en los ítems, lo que es bastante común en un control ComboBox, pero ya que el ComboBoxItem es un ContentControl, podemos incluir prácticamente cualquier cosa en su contenido. Intentemos con una lista de ítems algo más sofisticada:

<Window x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxCustomContentSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ComboBoxCustomContentSample" Height="150" Width="200">
    <StackPanel Margin="10">
        <ComboBox>
            <ComboBoxItem>
                <StackPanel Orientation="Horizontal">
                    <Image Source="/WpfTutorialSamples;component/Images/bullet_red.png" />
                    <TextBlock Foreground="Red">Red</TextBlock>
                </StackPanel>
            </ComboBoxItem>
            <ComboBoxItem>
                <StackPanel Orientation="Horizontal">
                    <Image Source="/WpfTutorialSamples;component/Images/bullet_green.png" />
                    <TextBlock Foreground="Green">Green</TextBlock>
                </StackPanel>
            </ComboBoxItem>
            <ComboBoxItem>
                <StackPanel Orientation="Horizontal">
                    <Image Source="/WpfTutorialSamples;component/Images/bullet_blue.png" />
                    <TextBlock Foreground="Blue">Blue</TextBlock>
                </StackPanel>
            </ComboBoxItem>
        </ComboBox>
    </StackPanel>
</Window>

Para cada uno de los ComboBoxItem ahora agregamos un StackPanel, en el que agregamos una Imagen y un TextBlock. Esto nos da un control total del contenido, así como la representación del texto, como se puede ver en la captura de pantalla, donde tanto el color del texto como la imagen indican un valor de color.

Enlazando datos al ComboBox

Como puedes ver en los primero ejemplos, definir manualmente los ítems de un control ComboBox es fácil utilizando XAML, pero probablemente pronto te encuentres en una situación donde necesites que los ítems provengas de algún tipo de fuente de datos, como una base de datos o símplemente una lista en memeoria. Usando el enlace de datos WPF y una plantilla personalizada, fácilmente podemos representar una lista de colores, incluyendo una vista previa del color:

<Window x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxDataBindingSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ComboBoxDataBindingSample" Height="200" Width="200">
    <StackPanel Margin="10">
        <ComboBox Name="cmbColors">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Rectangle Fill="{Binding Name}" Width="16" Height="16" Margin="0,2,5,2" />
                        <TextBlock Text="{Binding Name}" />
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
    </StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;

namespace WpfTutorialSamples.ComboBox_control
{
	public partial class ComboBoxDataBindingSample : Window
	{
		public ComboBoxDataBindingSample()
		{
			InitializeComponent();
			cmbColors.ItemsSource = typeof(Colors).GetProperties();
		}
	}
}

Es muy simple: En el código anterior, obtengo la lista de todos los colores utilizando un enfoque basado en Reflection con la clase Colors. Asigno la lista a la propiedad ItemsSource del ComboBox, el cual entonces representa cada color utilizando la plantilla que he definido en la porción XAML.

Cada elemento, según lo define el ItemTemplate, consta de un StackPanel con un Rectángulo y un TextBlock, cada uno vinculado al valor del color. Esto nos da una lista completa de colores, con un esfuerzo mínimo, y también se ve bastante bien, ¿verdad?

IsEditable

En los primeros ejemplos, el usuario solo pudo seleccionar de nuestra lista de elementos, pero una de las cosas interesantes de ComboBox es que admite la posibilidad de permitir que el usuario seleccione de una lista de elementos o ingrese su propio valor. Esto es extremadamente útil en situaciones en las que desea ayudar al usuario dándoles un conjunto predefinido de opciones, mientras les da la opción de ingresar manualmente el valor deseado. Todo esto está controlado por la propiedad IsEditable , que cambia bastante el comportamiento y el aspecto del ComboBox:

<Window x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxEditableSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ComboBoxEditableSample" Height="150" Width="200">
    <StackPanel Margin="10">
        <ComboBox IsEditable="True">
            <ComboBoxItem>ComboBox Item #1</ComboBoxItem>
            <ComboBoxItem>ComboBox Item #2</ComboBoxItem>
            <ComboBoxItem>ComboBox Item #3</ComboBoxItem>
        </ComboBox>
    </StackPanel>
</Window>

Como puede ver, puedo ingresar un valor completamente diferente o elegir uno de la lista. Si se selecciona de la lista, simplemente sobrescribe el texto de ComboBox.

Como un pequeño bono encantador, ComboBox intentará automáticamente ayudar al usuario a seleccionar un valor existente cuando el usuario comience a escribir, como puede ver en la siguiente captura de pantalla, donde comencé a escribir "Co":

De forma predeterminada, la coincidencia no distingue entre mayúsculas y minúsculas, pero puede hacerlo estableciendo IsTextSearchCaseSensitive en True. Si no quieres este comportamiento de autocompletar, puede deshabilitarlo configurando IsTextSearchEnabled en False.

Trabajando con la selección del ComboBox

Una parte clave del uso del control ComboBox es poder leer la selección del usuario e incluso controlarla con código. En el siguiente ejemplo, he reutilizado el ejemplo de ComboBox enlazado a datos, pero se agregaron algunos botones para controlar la selección. También he usado el evento SelectionChanged para capturar cuando el elemento seleccionado se cambia, ya sea por código o por el usuario, y actúa sobre él.

Aquí está la muestra:

<Window x:Class="WpfTutorialSamples.ComboBox_control.ComboBoxSelectionSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ComboBoxSelectionSample" Height="125" Width="250">
    <StackPanel Margin="10">
        <ComboBox Name="cmbColors" SelectionChanged="cmbColors_SelectionChanged">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Rectangle Fill="{Binding Name}" Width="16" Height="16" Margin="0,2,5,2" />
                        <TextBlock Text="{Binding Name}" />
                    </StackPanel>
                </DataTemplate>
            </ComboBox.ItemTemplate>
        </ComboBox>
        <WrapPanel Margin="15" HorizontalAlignment="Center">
            <Button Name="btnPrevious" Click="btnPrevious_Click" Width="55">Previous</Button>
            <Button Name="btnNext" Click="btnNext_Click" Margin="5,0" Width="55">Next</Button>
            <Button Name="btnBlue" Click="btnBlue_Click" Width="55">Blue</Button>
        </WrapPanel>
    </StackPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Windows;
using System.Windows.Media;

namespace WpfTutorialSamples.ComboBox_control
{
	public partial class ComboBoxSelectionSample : Window
	{
		public ComboBoxSelectionSample()
		{
			InitializeComponent();
			cmbColors.ItemsSource = typeof(Colors).GetProperties();
		}

		private void btnPrevious_Click(object sender, RoutedEventArgs e)
		{
			if(cmbColors.SelectedIndex > 0)
				cmbColors.SelectedIndex = cmbColors.SelectedIndex - 1;
		}

		private void btnNext_Click(object sender, RoutedEventArgs e)
		{
			if(cmbColors.SelectedIndex < cmbColors.Items.Count-1)
				cmbColors.SelectedIndex = cmbColors.SelectedIndex + 1;
		}

		private void btnBlue_Click(object sender, RoutedEventArgs e)
		{
			cmbColors.SelectedItem = typeof(Colors).GetProperty("Blue");
		}

		private void cmbColors_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
		{
			Color selectedColor = (Color)(cmbColors.SelectedItem as PropertyInfo).GetValue(null, null);
			this.Background = new SolidColorBrush(selectedColor);
		}
	}
}

La parte interesante de este ejemplo son los tres controladores de eventos para nuestros tres botones, así como el controlador de eventos SelectionChanged . En los dos primeros, seleccionamos el elemento anterior o siguiente leyendo la propiedad SelectedIndex y luego restando o agregando uno. Bastante simple y fácil de trabajar.

En el tercer controlador de eventos, usamos SelectedItem para seleccionar un elemento específico basado en el valor. Hago un poco de trabajo extra aquí (usando la reflexión de .NET), porque ComboBox está vinculado a una lista de propiedades, cada una de las cuales es un color, en lugar de una simple lista de colores, pero básicamente se trata de dar el valor contenido por uno de los elementos de la propiedad SelectedItem .

En el cuarto y último controlador de eventos, respondo al cambio del elemento seleccionado. Cuando eso sucede, leo el color seleccionado (una vez más usando Reflexión, como se describió anteriormente) y luego use el color seleccionado para crear un nuevo pincel de fondo para la Ventana. El efecto se puede ver en la captura de pantalla.

Si está trabajando con un ComboBox editable (propiedad IsEditable establecida en true), puede leer la propiedad Texto para conocer el valor del usuario ha entrado o seleccionado.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!