TOC

This article has been localized into French by the community.

Les contrôles de listes:

Le contrôle ComboBox

Le contrôle ComboBox ressemble beaucoup au ListBox mais prend peu de place, sa liste est par défaut masquée lorsqu'il n'est pas sélectionné. Il est très utilisé mais pour nous assurer que chacun comprend comment il se présente et fonctionne, nous allons nous y plonger grace a un exemple simple.

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

Dans la capture d'écran, j'ai activé le contrôle en cliquant dessus, provoquant l'affichage de la liste des éléments. Comme vous pouvez le voir dans le code, le ComboBox, dans sa forme simple, est très facile à utiliser. Tout ce que j'ai fait ici est d'ajouter manuellement certains éléments, ce qui en fait l'un sélectionné par défaut en définissant la propriété IsSelected dessus.

Contenu personnalisé

Dans le premier exemple, les éléments de la liste ne sont que du texte, ce qui est plutôt courant pour le contrôle ComboBox. Mais depuis que le ComboBoxItem est un ContentControl, on peut presque mettre tout ce qu'on veut comme type de contenu. Essayons de faire une liste d'éléments un peu plus complexe :

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

Chacun des ComboBoxItem se compose d'un StackPanel horizontal dans lequel sont ajoutés une Image puis un TextBlock. L'utilisation d'un TextBlock permet d'aller plus loin dans la modification du contenu. Comme on peut le voir sur la copie d'écran, chaque élément présente de 3 manières la couleur : l'icône, le texte et la couleur du texte.

Lier les données à la Boîte de Combo (ComboBox)

Comme vous pouvez le constater par les premiers exemples, définir manuellement les items du contrôle de la boîte combo (ComboBox) est facile lorsqu'on utilise XAML, mais vous allez bientôt vous retrouver dans une situation où vous avez besoin que les items viennent d'une quelconque source de données, comme une base de données ou seulement une liste en mémoire. En utilisant la liaison de données WPF et un modèle personnalisable, nous pouvons facilement fournir une liste couleurs, incluant un aperçu de la couleur:

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

En réalité c'est très facile: Dans le code-arrière, j'obtiens une liste de toutes les couleurs en utilisant une approche basée sur la Réflexion (Reflexion) avec la classe Couleurs (Colors). Je lui attribue la propriété Source d'item (ItemsSource) de la boîte combo (ComboBox), qui par la suite donne chaque couleur utilisant le modèle que j'ai défini dans la partie XAML.

Chaque item, comme défini par le Modèle Item (ItemTemplate), consiste d'un panneau de pile (StackPanel) avec un Rectangle et un Bloc de Texte (TextBlock), chacun étant lié à la valeur couleur. Ceci nous donne une liste complète de couleurs, avec un minimum d'effort - et ça a l'air très bien aussi, n'est-ce pas?

Est Éditable (IsEditable)

Dans les premiers exemples, l'utilisateur était seulement capable de sélectionner à partir de notre liste d'items, mais l'une des choses sympa de la Boîte Combo (ComboBox) c'est qu'elle soutient la possibilité de laisser l'utilisateur sélectionner à partir d'une liste d'items mais aussi d'entrer ses propres valeurs. Ceci est extrêmement utile dans les situations où vous voulez aider l'utilisateur en lui donnant une série d'options pré-définie, tout en lui donnant l'option d'entrer manuellement la valeur désirée. Tout ceci est contrôlé par la propriété Est Éditable (IsEditable), ce qui change pas mal le comportement et l'allure de la Boîte Combo (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>

Comme vous pouvez le constater, je peux entrer une valeur complètement différente ou en choisir une à partir de la liste. Si choisie à partir de la liste, elle écrase le texte de la Boîte Combo (ComboBox).

Comme un joli petit extra, la Boîte Combo (ComboBox) va automatiquement essayer d'aider l'utilisateur à sélectionner une valeur existante lorsque l'utilisateur débute l'écriture, comme vous pouvez le voir à partir de la prochaine capture d'écran, où j'ai tout juste commencé à écrire "Co":

Par défaut, la correspondance n'est pas sensible à la casse mais vous pouvez faire en sorte qu'elle le soit en configurant la propriété IsTextSearchCaseSensitive à Vrai (True). Si vous ne désirez pas du tout de ce comportement auto complétion, vous pouvez le désactiver en configurant la propriété IsTextSearchEnabled à Faux (False).

Travaillant avec la sélection Boîte Combo (ComboBox)

La partie clé d'utiliser le contrôle Boîte Combo (ComboBox) est d'être capable de lire la sélection utilisateur, et même la contrôler avec du code. Dans le prochain exemple, j'ai ré-utilisé l'exemple de liaison de données de la Boîte Combo (ComboBox), mais j'ai ajouté quelques pour contrôler la sélection. J'ai aussi utilisé l'événement SélectionChangée (SelectionChanged) pour capturer quand l'item sélectionné est changé, soit par code ou par l'utilisateur, et agir sur lui.

Voici l'échantillon:

<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 partie intéressante de cet exemple concerne les trois gestionnaires d'événements pour nos trois boutons, ainsi que le gestionnaire d'événement SelectionChanged . Dans les deux premiers, nous sélectionnons l'élément précédent ou suivant en lisant la propriété SelectedIndex puis en soustrayant ou en ajoutant un. Assez simple et facile à travailler.

Dans le troisième gestionnaire d'événements, nous utilisons la propriété SelectedItem pour sélectionner un élément spécifique en fonction de la valeur. Je fais un peu de travail supplémentaire ici (en utilisant la réflexion .NET), car le ComboBox est lié à une liste de propriétés, chacune étant une couleur, au lieu d'une simple liste de couleurs, mais en gros, il s'agit de donner la valeur contenue par un des éléments de la propriété SelectedItem .

Dans le quatrième et dernier gestionnaire d'événements, je signifie que l'élément sélectionné est modifié. Lorsque cela se produit, la couleur sélectionnée est lue (à nouveau en utilisant la réflexion .NET, comme décrit ci-dessus), puis j'utilise la couleur sélectionnée pour créer un nouveau pinceau d'arrière-plan pour la fenêtre. L'effet est visible sur la capture d'écran.

Si vous travaillez avec une Boîte Combo (ComboBox) éditable (propriété IsEditable configurée à Vrai (True)), vous pouvez lire la propriété Texte (Text) pour connaître la valeur entrée ou sélectionnée par l'utilisateur.


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!