TOC

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

Dialogs:

Creating a custom input dialog

Dans les précédents articles, nous avons vu l'utilisation des boîtes de dialogues intégrées dans WPF ; cela étant, créer votre propre boîte de dialogue est presque aussi simple. En fait, vous devez simplement créer une fenêtre, y placer les contrôles souhaités et l'afficher.

Cependant, Il reste quelque éléments à ne pas oublier lors de la création de boite de dialogues, afin de s'assurer que votre application réagissent comme tout autre application Windows. Dans cet article nous allons voir comment créer une boite de dialogue simple proposant à l'utilisateur une question et qui retournera la réponse. Ainsi nous verrons petit à petit les différents réflexes à adopter.

Création de la boite de dialogue

Pour cette boite de dialogue, Je voulais juste un Label demandant à l'utilisateur une information à son propos, une TextBox permettant de répondre, Et les habituel boutons "Ok" et "Annuler". J'ai décidé d'ajouter de plus une icône à ma boite de dialogue, pour une meilleur esthétique. Voici le résultat :

Et voici le code pour cette boite de dialogue :

<Window x:Class="WpfTutorialSamples.Dialogs.InputDialogSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Input" SizeToContent="WidthAndHeight" WindowStartupLocation="CenterScreen"
        ContentRendered="Window_ContentRendered">
    <Grid Margin="15">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Image Source="/WpfTutorialSamples;component/Images/question32.png" Width="32" Height="32" Grid.RowSpan="2" Margin="20,0" />

        <Label Name="lblQuestion" Grid.Column="1">Question:</Label>
        <TextBox Name="txtAnswer" Grid.Column="1" Grid.Row="1" MinWidth="250">Answer</TextBox>

        <WrapPanel Grid.Row="2" Grid.ColumnSpan="2" HorizontalAlignment="Right" Margin="0,15,0,0">
            <Button IsDefault="True" Name="btnDialogOk" Click="btnDialogOk_Click" MinWidth="60" Margin="0,0,10,0">_Ok</Button>
            <Button IsCancel="True" MinWidth="60">_Cancel</Button>
        </WrapPanel>
    </Grid>
</Window>
using System;
using System.Windows;

namespace WpfTutorialSamples.Dialogs
{
	public partial class InputDialogSample : Window
	{
		public InputDialogSample(string question, string defaultAnswer = "")
		{
			InitializeComponent();
			lblQuestion.Content = question;
			txtAnswer.Text = defaultAnswer;
		}

		private void btnDialogOk_Click(object sender, RoutedEventArgs e)
		{
			this.DialogResult = true;
		}

		private void Window_ContentRendered(object sender, EventArgs e)
		{
			txtAnswer.SelectAll();
			txtAnswer.Focus();
		}

		public string Answer
		{
			get { return txtAnswer.Text; }
		}
	}
}

Le code est plutôt simple, mais voici les différents éléments auxquels vous devez faire attention :

XAML

Dans la partie XAML, j'ai utilisé un objet Grid pour l'affichage des contrôles - rien de sophistiqué là-dedans. J'ai retiré les propriétés Width et Height de la fenêtre et, à la place, j'ai défini la fenêtre en redimensionnement automatique pour s'adapter au contenu - cela a un sens dans le cas d'une boîte de dialogue, si bien que vous n'avez pas besoin de régler finement la taille pour que tout s'affiche correctement. A la place, utilisez les propriétés de marge et de taille minimum pour vous assurer que les éléments apparaissent comme vous le voulez, tout en laissant la possibilité à l'utilisateur de redimensionner la boîte de dialogue.

Une autre propriété de la fenêtre que j'ai modifié est sa position de départ WindowStartupLocation. Pour une boite de dialogue comme celle-ci, et probablement pour tout autres fenêtres secondaires, vous devriez changer cette propriété à "CenterScreen" ou "CenterOwner" (le paramètre par défaut laissant Windows décider de la position) , si vous n'avez pas manuellement définie les paramètres Top et Left auparavant.

Faites également particulièrement attention aux deux propriétés que j'ai utilisées sur les boutons de la boite de dialogue: IsCancel et IsDefault. "IsCancel" indique à WPF que, lorsque l'utilisateur clic sur ce bouton, le DialogResult de notre fenêtre doit être définie à faux (false) et que la fenêtre doit ensuite être fermé. Cela permet aussi de s'assurer que l'utilisateur puisse appuyer sur la touche Esc du clavier pour fermer la fenêtre, ce qui devrait toujours être possible avec une boite de dialogue Windows.

La propriété IsDefault donne le focus au bouton "Ok" et s'assure que lorsque l'utilisateur appuie sur la touche Entrer, ce bouton soit déjà activé. Dans ce cas un gestionnaire d'événement est nécessaire pour définir le "DialogResult", comme décrit ultérieurement.

Code-behind

Dans le Code-behind, j'ai changé le constructeur pour qu'il prenne deux paramètres, dont un optionnel. Ils permettent de définir la question ainsi que la réponse par défaut, si il est défini, dans le contrôle UI.

Le bouton Ok possède un récupérateur d’évènement permettant de passer la propriété de DialogResult à truelorsqu'il est cliqué afin de signaler que l'utilisateur accepte la valeur saisie. Nous n'en avons pas besoin pour le bouton Cancel car WPF le récupère lorsque nous avons mis la propriété IsCancel à true comme décrit ci dessus.

Afin de donner le focus à la TextBox lors de l'ouverture de la boite de dialogue, je me suis abonné à l’événement ContentRendered qui permet de sélectionner tout le texte et mettre le focus sur l’élément. Si je veux juste donner le focus, je peux utiliser la propriété FocusManager.FocusedElement de la fenêtre, mais dans notre cas je voulais également sélectionner le texte pour permettre à l'utilisateur de remplacer instantanément la réponse par défaut si celle ci ne lui convient pas.

Un dernier détail pour la propriété Answer que j'ai implémentée. Elle donne simplement l'accès à la valeur saisie dans le control TextBox, mais c'est une bonne pratique de fournir une propriété avec les valeurs de retour de la boite de dialogue plutôt que d’accéder directement aux contrôles depuis l’extérieur de la fenêtre. Cela permet également de modifier la valeur de retour avant de la retourner, si cela est nécessaire.

Utiliser une boite de dialogue

Après avoir mis en place les éléments expliqués précédemment, nous sommes prêt à utiliser notre boite de dialogue. C'est vraiment très simple, j'ai donc créé une petite application pour la tester. Voici le code :

<Window x:Class="WpfTutorialSamples.Dialogs.InputDialogAppSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="InputDialogAppSample" Height="150" Width="300">
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
        <TextBlock>Hello, world. My name is:</TextBlock>
        <TextBlock Name="lblName" Margin="0,10" TextAlignment="Center" FontWeight="Bold">[No name entered]</TextBlock>
        <Button Name="btnEnterName" Click="btnEnterName_Click">Enter name...</Button>
    </StackPanel>
</Window>
using System;
using System.Windows;

namespace WpfTutorialSamples.Dialogs
{
	public partial class InputDialogAppSample : Window
	{
		public InputDialogAppSample()
		{
			InitializeComponent();
		}

		private void btnEnterName_Click(object sender, RoutedEventArgs e)
		{
			InputDialogSample inputDialog = new InputDialogSample("Please enter your name:", "John Doe");
			if(inputDialog.ShowDialog() == true)
				lblName.Text = inputDialog.Answer;
		}
	}
}

Rien de spécial ici, juste deux contrôle TextBoxet un bouton pour lancer la boite de dialogue. Dans le gestionnaire d'événement du Clic, on instancie la fenêtre InputDialogSample, qui affiche une question et une réponse par défaut, puis nous utilisons la méthode ShowDialog() pour l'afficher. Vous devez toujours utiliser la méthode ShowDialog() et non la méthode Show() pour une boite modal comme celle-ci.

Si le résultat de la boite de dialogue est true, signifiant que l'utilisateur a cliqué sur le bouton Ok ou sur la touche Entrée, le résultat est assignée au nom du Label. Voila tout !

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!