Partager via


Vue d'ensemble des boîtes de dialogue

Les applications autonomes possèdent en général une fenêtre principale qui affiche les données principales sur lesquelles l'application fonctionne et qui expose également les fonctionnalités pour traiter ces données à travers des mécanismes user interface (UI) comme les barres de menus, les barres d'outils et les barres d'état. Une application non triviale peut afficher également des fenêtres supplémentaires pour effectuer les opérations suivantes :

  • Afficher des informations spécifiques aux utilisateurs.

  • Rassembler des informations provenant des utilisateurs.

  • Afficher et rassembler des informations.

Ces types de fenêtres sont connus sous le nom de boîtes de dialogue, et il en existe deux types : la boîte de dialogue modale et la boîte de dialogue non modale.

Une boîte de dialogue modale est affichée par une fonction lorsque la fonction a besoin de données supplémentaires de la part d'un utilisateur pour continuer. Parce que la fonction dépend de la boîte de dialogue modale pour rassembler des données, celle-ci empêche également un utilisateur d'activer d'autres fenêtres dans l'application pendant qu'elle reste ouverte. Dans la plupart des cas, une boîte de dialogue modale permet à un utilisateur de signaler lorsqu'il a fini d'utiliser la boîte de dialogue modale en appuyant sur le bouton OK ou Annuler. Le fait d'appuyer sur le bouton OK indique qu'un utilisateur a entré des données et souhaite que la fonction poursuive le traitement de ces données. Le fait d'appuyer sur le bouton Annuler indique qu'un utilisateur souhaite que la fonction arrête complètement l'exécution. Les exemples les plus courants de boîtes de dialogue modales sont indiqués pour ouvrir, enregistrer et imprimer des données.

Une boîte de dialogue non modale, en revanche, n'empêche pas un utilisateur d'activer d'autres fenêtres pendant qu'elle est ouverte. Par exemple, si un utilisateur souhaite rechercher des occurrences d'un mot particulier dans un document, une fenêtre principale ouvrira souvent une boîte de dialogue pour lui demander le mot qu'il recherche. Puisque rechercher un mot n'empêche pas un utilisateur de modifier le document, il n'est pas nécessaire, toutefois, que la boîte de dialogue soit une boîte de dialogue modale. Une boîte de dialogue non modale fournit au moins un bouton Fermer pour fermer la boîte de dialogue et peut fournir des boutons supplémentaires pour exécuter des fonctions spécifiques, telles que le bouton Rechercher le suivant pour rechercher le mot suivant correspondant aux critères de recherche d'une recherche de mots.

Windows Presentation Foundation (WPF) vous permet de créer plusieurs types de boîtes de dialogue, notamment des boîtes de message, des boîtes de dialogue courantes et des boîtes de dialogue personnalisées. Cette rubrique présente chacune d'entre elles, et la rubrique Boîte de dialogue, exemple fournit des exemples correspondants.

Cette rubrique comprend les sections suivantes.

  • Messages
  • Boîtes de dialogue courantes
  • Boîtes de dialogues personnalisées
  • Rubriques connexes

Messages

Un message est une boîte de dialogue qui peut être utilisée pour afficher des informations textuelles et permettre aux utilisateurs de prendre des décisions à l'aide de boutons. L'illustration suivante montre un message qui affiche des informations textuelles, pose une question et fournit trois boutons à l'utilisateur pour répondre à la question.

Boîte de dialogue Traitement de texte

Pour créer une boîte de message, utilisez la classe MessageBox. MessageBox vous permet de configurer le texte de la boîte de message, son titre, son icône et ses boutons, à l'aide de code semblable au suivant.

' Configure the message box to be displayed
Dim messageBoxText As String = "Do you want to save changes?"
Dim caption As String = "Word Processor"
Dim button As MessageBoxButton = MessageBoxButton.YesNoCancel
Dim icon As MessageBoxImage = MessageBoxImage.Warning
// Configure the message box to be displayed
string messageBoxText = "Do you want to save changes?";
string caption = "Word Processor";
MessageBoxButton button = MessageBoxButton.YesNoCancel;
MessageBoxImage icon = MessageBoxImage.Warning;

Pour afficher un message, appelez la méthode static Show, comme cela est indiqué dans le code suivant.

' Display message box
MessageBox.Show(messageBoxText, caption, button, icon)
// Display message box
MessageBox.Show(messageBoxText, caption, button, icon);

Lorsque le code qui affiche un message doit détecter et traiter la décision de l'utilisateur (le bouton utilisé), le code peut vérifier le résultat du message, comme illustré dans le code suivant.

' Display message box
Dim result As MessageBoxResult = MessageBox.Show(messageBoxText, caption, button, icon)

' Process message box results
Select Case result
    Case MessageBoxResult.Yes
        ' User pressed Yes button
        ' ...
    Case MessageBoxResult.No
        ' User pressed No button
        ' ...
    Case MessageBoxResult.Cancel
        ' User pressed Cancel button
        ' ...
End Select
// Display message box
MessageBoxResult result = MessageBox.Show(messageBoxText, caption, button, icon);

// Process message box results
switch (result)
{
    case MessageBoxResult.Yes:
        // User pressed Yes button
        // ...
        break;
    case MessageBoxResult.No:
        // User pressed No button
        // ...
        break;
    case MessageBoxResult.Cancel:
        // User pressed Cancel button
        // ...
        break;
}

Pour plus d'informations sur l'utilisation des boîtes de message, consultez MessageBox, MessageBox, exemple et Boîte de dialogue, exemple.

Bien que MessageBox puisse offrir une expérience utilisateur de boîte de dialogue simplifiée, l'utilisation de MessageBox présente l'avantage d'être le seul type de fenêtre qui peut être affiché par les applications qui s'exécutent dans un bac à sable (sandbox) de sécurité de confiance partielle (consultez Sécurité (WPF)), telle que XAML browser applications (XBAPs).

La plupart des boîtes de dialogue affichent et rassemblent des données plus complexes que le résultat d'un message, y compris le texte, la sélection (les cases à cocher), la sélection mutuellement exclusive (les cases d'option) et la sélection de liste (les zones de liste, les zones de liste déroulante modifiables, les zones de liste déroulante). Pour celles-ci, Windows Presentation Foundation (WPF) propose plusieurs boîtes de dialogue courantes et vous permet de créer vos propres boîtes de dialogue, bien que l'utilisation de l'une d'entre elles soit limitée aux applications s'exécutant avec un niveau de confiance totale.

Boîtes de dialogue courantes

Windows implémente diverses boîtes de dialogue réutilisables qui sont communes à toutes les applications, y compris les boîtes de dialogue pour ouvrir, enregistrer et imprimer des fichiers. Puisque ces boîtes de dialogue sont implémentées par le système d'exploitation, elles peuvent être partagées entre toutes les applications qui s'exécutent sur le système d'exploitation, ce qui permet une expérience cohérente à l'utilisateur ; lorsque les utilisateurs sont familiarisés avec l'utilisation d'une boîte de dialogue fournie par le système d'exploitation dans une application, ils n'ont pas besoin d'apprendre comment l'utiliser dans d'autres applications. Comme ces boîtes de dialogue sont disponibles pour toutes les applications et comme elles aident à fournir une expérience utilisateur cohérente, celles-ci sont connues sous le nom de boîtes de dialogue courantes.

Windows Presentation Foundation (WPF) encapsule les boîtes de dialogue courantes Ouvrir un fichier, Enregistrer le fichier et Imprimer et les expose comme des classes managées pour que vous puissiez les utiliser dans des applications autonomes. Cette rubrique fournit une brève vue d'ensemble de chacune d'elles :

Boîte de dialogue Ouvrir un fichier

La boîte de dialogue Ouvrir un fichier, affichée dans l'illustration suivante, est utilisée par les fonctionnalités d'ouverture de fichier pour récupérer le nom d'un fichier à ouvrir.

Boîte de dialogue Ouvrir

La boîte de dialogue courante Ouvrir un fichier est implémentée en tant que classe OpenFileDialog et se trouve dans l'espace de noms Microsoft.Win32. Le code suivant montre comment en créer, configurer et afficher une et comment traiter le résultat.

' Configure open file dialog box
Dim dlg As New Microsoft.Win32.OpenFileDialog()
dlg.FileName = "Document" ' Default file name
dlg.DefaultExt = ".txt" ' Default file extension
dlg.Filter = "Text documents (.txt)|*.txt" ' Filter files by extension

' Show open file dialog box
Dim result? As Boolean = dlg.ShowDialog()

' Process open file dialog box results
If result = True Then
    ' Open document
    Dim filename As String = dlg.FileName
End If
// Configure open file dialog box
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
dlg.FileName = "Document"; // Default file name
dlg.DefaultExt = ".txt"; // Default file extension
dlg.Filter = "Text documents (.txt)|*.txt"; // Filter files by extension

// Show open file dialog box
Nullable<bool> result = dlg.ShowDialog();

// Process open file dialog box results
if (result == true)
{
    // Open document
    string filename = dlg.FileName;
}

Pour plus d'informations sur la boîte de dialogue Ouvrir un fichier, consultez Microsoft.Win32.OpenFileDialog.

RemarqueRemarque

OpenFileDialog peut être utilisé pour récupérer en toute sécurité des noms de fichier par les applications s'exécutant avec un niveau de confiance partielle (consultez Sécurité (WPF)).

Boîte de dialogue Enregistrer le fichier

La boîte de dialogue Enregistrer le fichier, affichée dans l'illustration suivante, est utilisée par les fonctionnalités d'enregistrement de fichier pour récupérer le nom d'un fichier à enregistrer.

Boîte de dialogue Enregistrer sous

La boîte de dialogue courante Enregistrer le fichier est implémentée en tant que classe SaveFileDialog et se trouve dans l'espace de noms Microsoft.Win32. Le code suivant montre comment en créer, configurer et afficher une et comment traiter le résultat.

' Configure save file dialog box
Dim dlg As New Microsoft.Win32.SaveFileDialog()
dlg.FileName = "Document" ' Default file name
dlg.DefaultExt = ".text" ' Default file extension
dlg.Filter = "Text documents (.txt)|*.txt" ' Filter files by extension

' Show save file dialog box
Dim result? As Boolean = dlg.ShowDialog()

' Process save file dialog box results
If result = True Then
    ' Save document
    Dim filename As String = dlg.FileName
End If
// Configure save file dialog box
Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
dlg.FileName = "Document"; // Default file name
dlg.DefaultExt = ".text"; // Default file extension
dlg.Filter = "Text documents (.txt)|*.txt"; // Filter files by extension

// Show save file dialog box
Nullable<bool> result = dlg.ShowDialog();

// Process save file dialog box results
if (result == true)
{
    // Save document
    string filename = dlg.FileName;
}

Pour plus d'informations sur la boîte de dialogue Enregistrer le fichier, consultez Microsoft.Win32.SaveFileDialog.

Boîte de dialogue Imprimer

La boîte de dialogue Imprimer, affichée dans l'illustration suivante, est utilisée par les fonctionnalités d'impression pour choisir et configurer l'imprimante vers laquelle un utilisateur souhaite imprimer des données.

Boîte de dialogue Imprimer

La boîte de dialogue Imprimer courante est implémentée en tant que classe PrintDialog et se trouve dans l'espace de noms System.Windows.Controls. Le code suivant montre comment en créer, configurer et afficher une.

' Configure printer dialog box
Dim dlg As New PrintDialog()
dlg.PageRangeSelection = PageRangeSelection.AllPages
dlg.UserPageRangeEnabled = True

' Show save file dialog box
Dim result? As Boolean = dlg.ShowDialog()

' Process save file dialog box results
If result = True Then
    ' Print document
End If
// Configure printer dialog box
System.Windows.Controls.PrintDialog dlg = new System.Windows.Controls.PrintDialog();
dlg.PageRangeSelection = PageRangeSelection.AllPages;
dlg.UserPageRangeEnabled = true;

// Show save file dialog box
Nullable<bool> result = dlg.ShowDialog();

// Process save file dialog box results
if (result == true)
{
    // Print document
}

Pour plus d'informations sur la boîte de dialogue Imprimer, consultez System.Windows.Controls.PrintDialog. Pour obtenir une présentation détaillée de l'impression dans WPF, consultez Vue d'ensemble de l'impression.

Boîtes de dialogues personnalisées

Bien que les boîtes de dialogue courantes soient utiles et doivent être utilisées lorsque cela est possible, celles-ci ne prennent pas en charge les spécifications des boîtes de dialogue spécifiques au domaine. Dans ces cas, vous devez créer vos propres boîtes de dialogue. Comme nous allons le voir, une boîte de dialogue est une fenêtre avec des comportements spéciaux. Window implémente ces comportements et, par conséquent, vous utilisez Window pour créer des boîtes de dialogue personnalisées, modales ou non.

Création d'une boîte de dialogue personnalisée modale

Cette rubrique montre comment utiliser Window pour créer une implémentation de boîte de dialogue modale type, en utilisant la boîte de dialogue Margins comme exemple (consultez Boîte de dialogue, exemple). La boîte de dialogue Margins est affichée dans l'illustration suivante.

Boîte de dialogue Marges

Configuration d'une boîte de dialogue modale

L'interface utilisateur pour une boîte de dialogue classique inclut ce qui suit :

  • Les différents contrôles requis pour rassembler les données souhaitées.

  • Affichage d'un bouton OK sur lequel les utilisateurs cliquent pour fermer la boîte de dialogue, retourner à la fonction puis poursuivre le traitement.

  • Affichage d'un bouton Annuler que les utilisateurs cliquent pour fermer la boîte de dialogue et arrêter le traitement de la fonction.

  • Affichage d'un bouton Fermer dans la barre de titre.

  • Affichage d'une icône.

  • Affichage des boutons Réduire, Agrandir et Restaurer.

  • Affichage d'un menu Système pour réduire, agrandir, restaurer et fermer la boîte de dialogue.

  • Ouverture au-dessus et dans le centre de la fenêtre qui a ouvert la boîte de dialogue.

  • Les boîtes de dialogue doivent être redimensionnables lorsque cela est possible ainsi, pour empêcher la boîte de dialogue d'être trop petite et pour fournir à l'utilisateur une taille par défaut utile, vous devez définir respectivement les dimensions par défaut ainsi que les dimensions minimales.

  • Appuyer sur la touche ÉCHAP doit être configuré comme un raccourci clavier qui provoque l'activation du bouton Annuler. Pour cela, il faut affecter true à la propriété IsCancel du bouton Annuler.

  • Appuyer sur la touche ENTRÉE (ou RETOUR) doit être configuré comme un raccourci clavier qui provoque l'activation du bouton OK. Pour cela, il faut affecter true à la propriété IsDefault du bouton OK.

Le code suivant illustre cette configuration.


<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.MarginsDialogBox"
    xmlns:local="clr-namespace:SDKSample"
    Title="Margins"
    Height="190"
    Width="300"
    MinHeight="10"
    MinWidth="300"
    ResizeMode="CanResizeWithGrip"
    ShowInTaskbar="False"
    WindowStartupLocation="CenterOwner" 
    FocusManager.FocusedElement="{Binding ElementName=leftMarginTextBox}">

  <Grid>


...


    <!-- Accept or Cancel -->
    <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="4">
      <Button Name="okButton" Click="okButton_Click" IsDefault="True">OK</Button>
      <Button Name="cancelButton" IsCancel="True">Cancel</Button>
    </StackPanel>

  </Grid >

</Window>
Imports System.Windows ' Window, RoutedEventArgs, IInputElement, DependencyObject
Imports System.Windows.Controls ' Validation
Imports System.Windows.Input ' Keyboard

Namespace SDKSample


Public Class MarginsDialogBox
    Inherits Window
    Public Sub New()
        Me.InitializeComponent()
    End Sub


...


End Class

End Namespace
using System.Windows; // Window, RoutedEventArgs, IInputElement, DependencyObject
using System.Windows.Controls; // Validation
using System.Windows.Input; // Keyboard

namespace SDKSample
{
    public partial class MarginsDialogBox : Window
    {
        public MarginsDialogBox()
        {
            InitializeComponent();
        }


...


    }
}

L'expérience utilisateur pour une boîte de dialogue s'étend également dans la barre de menus de la fenêtre qui ouvre la boîte de dialogue. Lorsqu'un élément de menu exécute une fonction nécessitant l'intervention de l'utilisateur à l'aide d'une boîte de dialogue avant la poursuite de la fonction, l'élément de menu pour la fonction aura un bouton de sélection dans son en-tête, comme indiqué ici.

<!--Main Window-->


...


<MenuItem Name="formatMarginsMenuItem" Header="_Margins..." Click="formatMarginsMenuItem_Click" />

Lorsqu'un élément de menu exécute une fonction qui affiche une boîte de dialogue ne nécessitant pas d'intervention de l'utilisateur, comme une boîte de dialogue À propos, un bouton de sélection n'est pas nécessaire.

Ouverture d'une boîte de dialogue modale

Une boîte de dialogue s'affiche en général comme résultat de la sélection par un utilisateur d'un élément de menu pour exécuter une fonction spécifique au domaine, telle que la définition des marges d'un document dans un traitement de texte. L'affichage d'une fenêtre en tant que boîte de dialogue est similaire à l'affichage d'une fenêtre normale, bien que cela nécessite une configuration supplémentaire spécifique à la boîte de dialogue. Le processus entier d'instanciation, de configuration et d'ouverture d'une boîte de dialogue est affiché dans le code suivant.


Imports System '  EventArgs
Imports System.ComponentModel '  CancelEventArgs
Imports System.Windows '  Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls '  TextChangedEventArgs
Imports Microsoft.Win32 '  OpenFileDialog

Namespace SDKSample

Public Class MainWindow
    Inherits Window


...


    Private Sub formatMarginsMenuItem_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Instantiate the dialog box
        Dim dlg As New MarginsDialogBox

        ' Configure the dialog box
        dlg.Owner = Me
        dlg.DocumentMargin = Me.documentTextBox.Margin

        ' Open the dialog box modally 
        dlg.ShowDialog()



...


End Sub


...


End Class

End Namespace
using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextChangedEventArgs
using Microsoft.Win32; // OpenFileDialog

namespace SDKSample
{
    public partial class MainWindow : Window
    {


...


        void formatMarginsMenuItem_Click(object sender, RoutedEventArgs e)
        {
            // Instantiate the dialog box
            MarginsDialogBox dlg = new MarginsDialogBox();

            // Configure the dialog box
            dlg.Owner = this;
            dlg.DocumentMargin = this.documentTextBox.Margin;

            // Open the dialog box modally 
            dlg.ShowDialog();



...


}


...


    }
}

Ici, le code passe les informations par défaut (les marges actuelles) à la boîte de dialogue. Il définit également la propriété Window.Owner avec une référence à la fenêtre qui affiche la boîte de dialogue. En général, vous devez toujours définir le propriétaire d'une boîte de dialogue pour fournir des comportements liés à l'état d'une fenêtre qui sont communs à toutes les boîtes de dialogue (consultez Vue d'ensemble des fenêtres WPF pour plus d'informations).

RemarqueRemarque

Vous devez définir un propriétaire pour prendre en charge l'automation de l'user interface (UI) des boîtes de dialogue (consultez Vue d'ensemble d'UI Automation).

Après la configuration de la boîte de dialogue, celle-ci est affichée sous forme modale en appelant la méthode ShowDialog.

Validation de données fournies par l'utilisateur

Lorsqu'une boîte de dialogue est ouverte et que l'utilisateur fournit les données requises, une boîte de dialogue est chargée de garantir que les données fournies sont valides pour les raisons suivantes :

  • Du point de vue de la sécurité, toutes les entrées doivent être validées.

  • Du point de vue spécifique au domaine, la validation des données empêche le traitement des données erronées par le code, ce qui pourrait éventuellement lever des exceptions.

  • Du point de vue de l'expérience utilisateur, une boîte de dialogue peut aider les utilisateurs en leur montrant les données non valides parmi celles qu'ils ont entrées.

  • Du point de vue du niveau de performance, la validation des données dans une application multicouche peut réduire le nombre d'allers-retours entre le client et la couche Application, en particulier lorsque l'application est composée de services Web ou de bases de données serveur.

Pour valider un contrôle dépendant dans WPF, vous devez définir une règle de validation et l'associer à la liaison. Une règle de validation est une classe personnalisée dérivée de ValidationRule. L'exemple suivant illustre une règle de validation, MarginValidationRule, qui vérifie qu'une valeur liée est Double et se trouve dans une plage spécifiée.

Imports System.Globalization
Imports System.Windows.Controls

Namespace SDKSample

Public Class MarginValidationRule
    Inherits ValidationRule

    Private _maxMargin As Double
    Private _minMargin As Double

    Public Property MaxMargin() As Double
        Get
            Return Me._maxMargin
        End Get
        Set(ByVal value As Double)
            Me._maxMargin = value
        End Set
    End Property

    Public Property MinMargin() As Double
        Get
            Return Me._minMargin
        End Get
        Set(ByVal value As Double)
            Me._minMargin = value
        End Set
    End Property

    Public Overrides Function Validate(ByVal value As Object, ByVal cultureInfo As CultureInfo) As ValidationResult

        Dim margin As Double

        ' Is a number?
        If Not Double.TryParse(CStr(value), margin) Then
            Return New ValidationResult(False, "Not a number.")
        End If

        ' Is in range?
        If ((margin < Me.MinMargin) OrElse (margin > Me.MaxMargin)) Then
            Dim msg As String = String.Format("Margin must be between {0} and {1}.", Me.MinMargin, Me.MaxMargin)
            Return New ValidationResult(False, msg)
        End If

        ' Number is valid
        Return New ValidationResult(True, Nothing)

    End Function

End Class

End Namespace
using System.Globalization;
using System.Windows.Controls;

namespace SDKSample
{
    public class MarginValidationRule : ValidationRule
    {
        double minMargin;
        double maxMargin;

        public double MinMargin
        {
            get { return this.minMargin; }
            set { this.minMargin = value; }
        }

        public double MaxMargin
        {
            get { return this.maxMargin; }
            set { this.maxMargin = value; }
        }

        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            double margin;

            // Is a number?
            if (!double.TryParse((string)value, out margin))
            {
                return new ValidationResult(false, "Not a number.");
            }

            // Is in range?
            if ((margin < this.minMargin) || (margin > this.maxMargin))
            {
                string msg = string.Format("Margin must be between {0} and {1}.", this.minMargin, this.maxMargin);
                return new ValidationResult(false, msg);
            }

            // Number is valid
            return new ValidationResult(true, null);
        }
    }
}

Dans ce code, la logique de validation d'une règle de validation est implémentée en substituant la méthode Validate, qui valide les données et retourne un ValidationResultapproprié.

Pour associer la règle de validation au contrôle dépendant, utilisez le balisage suivant.

<Window 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.MarginsDialogBox"
    xmlns:local="clr-namespace:SDKSample"
    Title="Margins"
    Height="190"
    Width="300"
    MinHeight="10"
    MinWidth="300"
    ResizeMode="CanResizeWithGrip"
    ShowInTaskbar="False"
    WindowStartupLocation="CenterOwner" 
    FocusManager.FocusedElement="{Binding ElementName=leftMarginTextBox}">

  <Grid>
    


...


<Label Grid.Column="0" Grid.Row="0">Left Margin:</Label>
<TextBox Name="leftMarginTextBox" Grid.Column="1" Grid.Row="0">
  <TextBox.Text>
    <Binding Path="Left" UpdateSourceTrigger="PropertyChanged">
      <Binding.ValidationRules>
        <local:MarginValidationRule MinMargin="0" MaxMargin="10" />
      </Binding.ValidationRules>
    </Binding>
  </TextBox.Text>
</TextBox>


...


</Window>

Une fois que la règle de validation est associée, WPF l'appliquera automatiquement lorsque les données sont entrées dans le contrôle dépendant. Lorsqu'un contrôle contient des données non valides, WPF affichera une bordure rouge autour du contrôle non valide, comme indiqué dans l'illustration suivante.

Marge gauche non valide

WPF ne restreint pas un utilisateur au contrôle non valide jusqu'à ce qu'il ait entré des données valides. C'est un bon comportement pour une boîte de dialogue ; un utilisateur doit pouvoir naviguer librement entre les contrôles d'une boîte de dialogue, que les données soient valides ou pas. Toutefois, cela signifie qu'un utilisateur peut entrer des données non valides et appuyer sur le bouton OK. Pour cette raison, votre code doit également valider tous les contrôles dans une boîte de dialogue lorsque l'utilisateur appuie sur le bouton OK en gérant l'événement Click.

Imports System.Windows ' Window, RoutedEventArgs, IInputElement, DependencyObject
Imports System.Windows.Controls ' Validation
Imports System.Windows.Input ' Keyboard

Namespace SDKSample


Public Class MarginsDialogBox
    Inherits Window


...


Private Sub okButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    ' Don't accept the dialog box if there is invalid data
    If Not Me.IsValid(Me) Then Return


...


    End Sub

    ' Validate all dependency objects in a window
    Private Function IsValid(ByVal node As DependencyObject) As Boolean

        ' Check if dependency object was passed and if dependency object is valid.
        ' NOTE: Validation.GetHasError works for controls that have validation rules attached 
        If ((Not node Is Nothing) AndAlso Validation.GetHasError(node)) Then
            ' If the dependency object is invalid, and it can receive the focus,
            ' set the focus
            If TypeOf node Is IInputElement Then
                Keyboard.Focus(DirectCast(node, IInputElement))
            End If
            Return False
        End If

        ' If this dependency object is valid, check all child dependency objects
        Dim subnode As Object
        For Each subnode In LogicalTreeHelper.GetChildren(node)
            If (TypeOf subnode Is DependencyObject AndAlso Not Me.IsValid(DirectCast(subnode, DependencyObject))) Then
                ' If a child dependency object is invalid, return false immediately,
                ' otherwise keep checking
                Return False
            End If
        Next

        ' All dependency objects are valid
        Return True

    End Function

End Class

End Namespace
using System.Windows; // Window, RoutedEventArgs, IInputElement, DependencyObject
using System.Windows.Controls; // Validation
using System.Windows.Input; // Keyboard

namespace SDKSample
{
    public partial class MarginsDialogBox : Window
    {


...


void okButton_Click(object sender, RoutedEventArgs e)
{
    // Don't accept the dialog box if there is invalid data
    if (!IsValid(this)) return;


...


        }

        // Validate all dependency objects in a window
        bool IsValid(DependencyObject node)
        {
            // Check if dependency object was passed
            if (node != null)
            {
                // Check if dependency object is valid.
                // NOTE: Validation.GetHasError works for controls that have validation rules attached 
                bool isValid = !Validation.GetHasError(node);
                if (!isValid)
                {
                    // If the dependency object is invalid, and it can receive the focus,
                    // set the focus
                    if (node is IInputElement) Keyboard.Focus((IInputElement)node);
                    return false;
                }
            }

            // If this dependency object is valid, check all child dependency objects
            foreach (object subnode in LogicalTreeHelper.GetChildren(node))
            {
                if (subnode is DependencyObject)
                {   
                    // If a child dependency object is invalid, return false immediately,
                    // otherwise keep checking
                    if (IsValid((DependencyObject)subnode) == false) return false;
                }
            }

            // All dependency objects are valid
            return true;
        }
    }
}

Ce code énumère tous les objets de dépendance sur une fenêtre et, si l'un deux n'est pas valide (tel que retourné par GetHasError, le contrôle non valide obtient le focus, la méthode IsValid retourne false et la fenêtre est considérée comme non valide.

Une fois qu'une boîte de dialogue est valide, elle peut se fermer en toute sécurité et retourner. Dans le cadre du processus de retour, elle doit retourner un résultat à l'appel de la fonction.

Définition du résultat de la boîte de dialogue modale

L'ouverture d'une boîte de dialogue à l'aide de ShowDialog revient fondamentalement à appeler une méthode : le code qui a ouvert la boîte de dialogue en utilisant ShowDialog attend que ShowDialog soit retourné. Lorsque ShowDialog est retourné, le code qui l'a appelé doit décider de poursuivre le traitement ou de l'interrompre, selon si l'utilisateur a appuyé ou pas sur le bouton OK ou sur le bouton Annuler. Pour faciliter cette décision, la boîte de dialogue doit retourner le choix de l'utilisateur comme une valeur Boolean qui est retournée à partir de la méthode ShowDialog.

Lorsque l'utilisateur clique sur le bouton OK, ShowDialog doit retourner true. Pour cela, il faut définir la propriété DialogResult de la boîte de dialogue lorsque l'utilisateur clique sur le bouton OK.

Notez que la définition de la propriété DialogResult provoque également la fermeture automatique de la fenêtre, ce qui diminue le besoin d'appeler Closeexplicitement.

Lorsque l'utilisateur clique sur le bouton Annuler, ShowDialog doit retourner false, ce qui requiert également la définition de la propriété DialogResult.

Imports System.Windows ' Window, RoutedEventArgs, IInputElement, DependencyObject
Imports System.Windows.Controls ' Validation
Imports System.Windows.Input ' Keyboard

Namespace SDKSample


Public Class MarginsDialogBox
    Inherits Window


...


Private Sub cancelButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    ' Dialog box canceled
    Me.DialogResult = False
End Sub


...


End Class

End Namespace
using System.Windows; // Window, RoutedEventArgs, IInputElement, DependencyObject
using System.Windows.Controls; // Validation
using System.Windows.Input; // Keyboard

namespace SDKSample
{
    public partial class MarginsDialogBox : Window
    {


...


void cancelButton_Click(object sender, RoutedEventArgs e)
{
    // Dialog box canceled
    this.DialogResult = false;
}


...


    }
}

Lorsque la propriété IsCancel d'un bouton a la valeur true et que l'utilisateur appuie sur le bouton Annuler ou sur la touche ÉCHAP, DialogResult a automatiquement la valeur false. La balise suivante a le même effet que le code précédent, sans avoir à gérer l'événement Click.

<Button Name="cancelButton" IsCancel="True">Cancel</Button>

Une boîte de dialogue retourne automatiquement false lorsqu'un utilisateur appuie sur le bouton Fermer dans la barre de titre ou s'il choisit l'élément de menu Fermer dans le menu Système.

Traitement des données retournées à partir d'une boîte de dialogue modale

Lorsque DialogResult est défini par une boîte de dialogue, la fonction qui l'a ouvert peut obtenir le résultat de la boîte de dialogue en inspectant la propriété DialogResult lorsque ShowDialog est retourné.


Imports System '  EventArgs
Imports System.ComponentModel '  CancelEventArgs
Imports System.Windows '  Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls '  TextChangedEventArgs
Imports Microsoft.Win32 '  OpenFileDialog

Namespace SDKSample

Public Class MainWindow
    Inherits Window


...


Private Sub formatMarginsMenuItem_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)


...


    ' Process data entered by user if dialog box is accepted
    If (dlg.DialogResult.GetValueOrDefault = True) Then
        Me.documentTextBox.Margin = dlg.DocumentMargin
    End If
End Sub


...


End Class

End Namespace
using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextChangedEventArgs
using Microsoft.Win32; // OpenFileDialog

namespace SDKSample
{
    public partial class MainWindow : Window
    {


...


void formatMarginsMenuItem_Click(object sender, RoutedEventArgs e)
{


...


    // Process data entered by user if dialog box is accepted
    if (dlg.DialogResult == true)
    {
        // Update fonts
        this.documentTextBox.Margin = dlg.DocumentMargin;
    }
}


...


    }
}

Si le résultat de la boîte de dialogue est true, la fonction utilise cela comme une indication pour récupérer et traiter les données fournies par l'utilisateur.

RemarqueRemarque

Une fois que ShowDialog a été retourné, une boîte de dialogue ne peut pas être rouverte.Vous devez alors créer une nouvelle instance.

Si le résultat de la boîte de dialogue est false, la fonction doit terminer le traitement de façon appropriée.

Création d'une boîte de dialogue personnalisée non modale

Une boîte de dialogue non modale, telle que la boîte de dialogue Rechercher affichée dans l'illustration suivante, a la même apparence fondamentale que la boîte de dialogue modale.

Boîte de dialogue Rechercher

Toutefois, le comportement est légèrement différent, comme décrit dans les sections suivantes.

Ouverture d'une boîte de dialogue non modale

L'ouverture d'une boîte de dialogue non modale s'effectue en appelant la méthode Show.

<!--Main Window-->

Imports System '  EventArgs
Imports System.ComponentModel '  CancelEventArgs
Imports System.Windows '  Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls '  TextChangedEventArgs
Imports Microsoft.Win32 '  OpenFileDialog

Namespace SDKSample

Public Class MainWindow
    Inherits Window


...


Private Sub editFindMenuItem_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim dlg As New FindDialogBox(Me.documentTextBox)
    dlg.Owner = Me
    AddHandler dlg.TextFound, New TextFoundEventHandler(AddressOf Me.dlg_TextFound)
    dlg.Show()
End Sub


...


End Class

End Namespace
using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextChangedEventArgs
using Microsoft.Win32; // OpenFileDialog

namespace SDKSample
{
    public partial class MainWindow : Window
    {


...


void editFindMenuItem_Click(object sender, RoutedEventArgs e)
{
    // Instantiate the dialog box
    FindDialogBox dlg = new FindDialogBox(this.documentTextBox);

    // Configure the dialog box
    dlg.Owner = this;
    dlg.TextFound += new TextFoundEventHandler(dlg_TextFound);

    // Open the dialog box modally
    dlg.Show();
}


...


    }
}

Contrairement à ShowDialog, Show est retourné immédiatement. Par conséquent, la fenêtre appelante ne peut pas déterminer quand la boîte de dialogue non modale est fermée et, donc, ne sait pas quand vérifier le résultat d'une boîte de dialogue ou obtenir des données à partir de celle-ci pour un traitement plus poussé. Au lieu de cela, la boîte de dialogue doit créer une autre manière de retourner des données vers la fenêtre appelante pour traitement.

Traitement des données retournées à partir d'une boîte de dialogue non modale

Dans cet exemple, FindDialogBox peut retourner un ou plusieurs résultats de la recherche vers la fenêtre principale, selon le texte recherché sans fréquence spécifique. Comme pour une boîte de dialogue modale, une boîte de dialogue non modale peut retourner des résultats en utilisant les propriétés. Toutefois, la fenêtre qui possède la boîte de dialogue doit savoir quand vérifier ces propriétés. Pour ce faire, la boîte de dialogue doit implémenter un événement déclenché à chaque fois que le texte est trouvé. À cette fin, FindDialogBox implémente le TextFoundEvent, qui requiert tout d'abord un délégué.

Namespace SDKSample
Public Delegate Sub TextFoundEventHandler(ByVal sender As Object, ByVal e As EventArgs)
End Namespace
using System;
namespace SDKSample
{
    public delegate void TextFoundEventHandler(object sender, EventArgs e);
}

À l'aide du délégué TextFoundEventHandler, FindDialogBox implémente TextFoundEvent.

Imports System ' EventArgs
Imports System.Windows ' Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls ' TextBox, TextChangedEventArgs
Imports System.Text.RegularExpressions ' Regex

Namespace SDKSample

Public Class FindDialogBox
    Inherits Window
    Public Event TextFound As TextFoundEventHandler
    Protected Overridable Sub OnTextFound()
        RaiseEvent TextFound(Me, EventArgs.Empty)
    End Sub


...


End Class

End Namespace
using System; // EventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextBox, TextChangedEventArgs
using System.Text.RegularExpressions; // Regex

namespace SDKSample
{
    public partial class FindDialogBox : Window
    {
        public event TextFoundEventHandler TextFound;
        protected virtual void OnTextFound()
        {
            TextFoundEventHandler textFound = this.TextFound;
            if (textFound != null) textFound(this, EventArgs.Empty);
        }


...


    }
}

Par conséquent, Find peut déclencher l'événement lorsqu'un résultat de recherche est trouvé.

Imports System ' EventArgs
Imports System.Windows ' Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls ' TextBox, TextChangedEventArgs
Imports System.Text.RegularExpressions ' Regex

Namespace SDKSample

Public Class FindDialogBox
    Inherits Window


...


Private Sub findNextButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)


...


Me.Index = match.Index
Me.Length = match.Length
RaiseEvent TextFound(Me, EventArgs.Empty)


...


End Sub


...


End Class

End Namespace
using System; // EventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextBox, TextChangedEventArgs
using System.Text.RegularExpressions; // Regex

namespace SDKSample
{
    public partial class FindDialogBox : Window
    {


...


void findNextButton_Click(object sender, RoutedEventArgs e)
{


...


// Text found
this.index = match.Index;
this.length = match.Length;
OnTextFound();


...


}


...


    }
}

La fenêtre propriétaire doit ensuite s'inscrire auprès de cet événement et gérer celui-ci.


Imports System '  EventArgs
Imports System.ComponentModel '  CancelEventArgs
Imports System.Windows '  Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls '  TextChangedEventArgs
Imports Microsoft.Win32 '  OpenFileDialog

Namespace SDKSample

Public Class MainWindow
    Inherits Window


...


    Private Sub dlg_TextFound(ByVal sender As Object, ByVal e As EventArgs)
        Dim dlg As FindDialogBox = DirectCast(sender, FindDialogBox)
        Me.documentTextBox.Select(dlg.Index, dlg.Length)
        Me.documentTextBox.Focus()
    End Sub

End Class

End Namespace
using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextChangedEventArgs
using Microsoft.Win32; // OpenFileDialog

namespace SDKSample
{
    public partial class MainWindow : Window
    {


...


        void dlg_TextFound(object sender, EventArgs e)
        {
            // Get the find dialog box that raised the event
            FindDialogBox dlg = (FindDialogBox)sender;

            // Get find results and select found text
            this.documentTextBox.Select(dlg.Index, dlg.Length);
            this.documentTextBox.Focus();
        }
    }
}

Fermeture d'une boîte de dialogue non modale

Parce que DialogResult n'a pas besoin d'être défini, une boîte de dialogue non modale peut être fermée à l'aide de mécanismes fournis par le système, dont notamment :

  • Cliquer sur le bouton Fermer dans la barre de titre.

  • Appuyer sur la touche ALT+F4.

  • Choisir Fermer dans le menu Système.

Votre code peut aussi appeler Close lorsque l'utilisateur clique sur le bouton Fermer.

Imports System ' EventArgs
Imports System.Windows ' Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls ' TextBox, TextChangedEventArgs
Imports System.Text.RegularExpressions ' Regex

Namespace SDKSample

Public Class FindDialogBox
    Inherits Window


...


    Private Sub closeButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        MyBase.Close()
    End Sub
End Class

End Namespace
using System; // EventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextBox, TextChangedEventArgs
using System.Text.RegularExpressions; // Regex

namespace SDKSample
{
    public partial class FindDialogBox : Window
    {


...


        void closeButton_Click(object sender, RoutedEventArgs e)
        {
            // Close dialog box
            this.Close();
        }
    }
}

Voir aussi

Concepts

Vue d'ensemble de Popup

Autres ressources

Exemple de boîte de dialogue (page éventuellement en anglais)

Exemple de contrôle personnalisé ColorPicker (page éventuellement en anglais)