Partager via


Vue d’ensemble des boîtes de dialogue

Les applications autonomes disposent généralement d’une fenêtre principale qui affiche les données principales sur lesquelles l’application fonctionne et expose les fonctionnalités permettant de traiter ces données via des mécanismes d’interface utilisateur tels que les barres de menus, les barres d’outils et les barres d’état. Une application non triviale peut également afficher des fenêtres supplémentaires pour effectuer les opérations suivantes :

  • Présenter des informations spécifiques aux utilisateurs

  • Recueillir des informations auprès des utilisateurs

  • Afficher et recueillir des informations

Ces types de fenêtres sont appelés boîtes de dialogue, et il en existe deux types : modales et non modales.

Une boîte de dialogue modale est affichée par une fonction quand celle-ci a besoin qu’un utilisateur fournisse des données supplémentaires pour continuer. Étant donné que la fonction dépend de la boîte de dialogue modale pour recueillir des données, celle-ci empêche également un utilisateur d’activer d’autres fenêtres de l’application pendant qu’elle reste ouverte. Dans la plupart des cas, une boîte de dialogue modale permet à un utilisateur de signaler quand il en a terminé avec elle en appuyant sur un bouton OK ou Annuler. Un appui 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. Un appui sur le bouton Annuler indique qu’un utilisateur veut arrêter complètement l’exécution de la fonction. Les exemples les plus courants de boîtes de dialogue modales sont présentés pour ouvrir, enregistrer et imprimer des données.

Une boîte de dialogue non modale, en revanche, n’empêche pas l’utilisateur d’activer d’autres fenêtres quand elle est ouverte. Par exemple, si un utilisateur souhaite rechercher des occurrences d’un mot particulier dans un document, une fenêtre principale peut ouvrir une boîte de dialogue pour l’inviter à spécifier le mot qu’il recherche. Puisque rechercher un mot n’empêche pas l’utilisateur de modifier le document, la boîte de dialogue n’a pas besoin d’être 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, comme un bouton Suivant pour rechercher le mot suivant qui correspond aux critères de recherche.

Windows Presentation Foundation (WPF) vous permet de créer plusieurs types de boîtes de dialogue, notamment les boîtes de dialogue, les boîtes de dialogue communes et les boîtes de dialogue personnalisées. Cette rubrique présente chaque type, et la rubrique Exemple de boîte de dialogue fournit des exemples correspondants.

Zones de message

Une boîte de message est une boîte de dialogue qui peut être utilisée pour afficher des informations textuelles et autoriser les utilisateurs à prendre des décisions avec des boutons. L’illustration suivante montre une boîte de message qui affiche des informations textuelles, pose une question et fournit à l’utilisateur trois boutons pour répondre à la question.

A Word Processor dialog box asking if you want to save the changes to the document before the application closes.

Pour créer une boîte de message, vous utilisez la MessageBox classe. MessageBox vous permet de configurer le texte de la zone de message, le titre, l’icône et les boutons, à l’aide de code comme suit.

// 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;
' 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

Pour afficher une boîte de message, vous appelez la staticShow méthode, comme illustré dans le code suivant.

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

Quand le code qui affiche une boîte de message doit détecter et traiter la décision de l’utilisateur (quel bouton a été enfoncé), le code peut inspecter le résultat de la boîte de message, comme indiqué dans le code suivant.

// 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;
}
' 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

Pour plus d’informations sur l’utilisation de boîtes de message, consultez MessageBox, Exemple MessageBox et Exemple de boîte de dialogue.

Bien qu’il MessageBox soit possible d’offrir une expérience utilisateur de boîte de dialogue simple, l’avantage de l’utilisation MessageBox est le seul type de fenêtre qui peut être affiché par les applications qui s’exécutent dans un bac à sable de sécurité de confiance partielle (voir Sécurité), comme les applications de navigateur XAML (XBAPs).

La plupart des boîtes de dialogue affichent et recueillent des données plus complexes que le résultat d’une boîte de message, notamment du texte, une sélection (cases à cocher), une sélection mutuellement exclusive (boutons radio) et une sélection dans une liste (zones de liste, zones de liste modifiable, zones de liste déroulante). Pour cela, Windows Presentation Foundation (WPF) fournit 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 ou l’autre soit limitée aux applications s’exécutant avec une confiance totale.

Boîtes de dialogue courantes

Windows implémente une variété de boîtes de dialogue réutilisables communes à toutes les applications, y compris les boîtes de dialogue permettant d’ouvrir des fichiers, d’enregistrer des fichiers et d’imprimer. Ces boîtes de dialogue étant implémentées par le système d’exploitation, elles peuvent être partagées par toutes les applications qui s’exécutent sur le système d’exploitation, ce qui favorise la cohérence de l’expérience utilisateur. Quand les utilisateurs sont habitués à utiliser une boîte de dialogue fournie par le système d’exploitation dans une application, ils n’ont pas besoin d’apprendre à utiliser cette boîte de dialogue dans d’autres applications. Puisque ces boîtes de dialogue sont accessibles à toutes les applications et qu’elles aident à fournir une expérience utilisateur cohérente, elles portent le nom de boîtes de dialogue communes.

Windows Presentation Foundation (WPF) encapsule le fichier ouvert, enregistre le fichier et imprime les boîtes de dialogue courantes et les expose en tant que classes managées que vous pouvez utiliser dans les applications autonomes. Cette rubrique fournit une brève présentation de chacune de ces boîtes de dialogue.

Boîte de dialogue Ouvrir un fichier

La boîte de dialogue d’ouverture de fichier, illustrée ci-dessous, est utilisée par la fonctionnalité d’ouverture de fichier pour récupérer le nom d’un fichier à ouvrir.

An Open dialog box showing the location to retrieve the file.

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

// 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;
}
' 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

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

Remarque

OpenFileDialog peut être utilisé pour récupérer en toute sécurité les noms de fichiers par les applications s’exécutant avec une approbation partielle (voir Sécurité).

Enregistrer le fichier (boîte de dialogue)

La boîte de dialogue d’enregistrement de fichier, illustrée ci-dessous, est utilisée par la fonctionnalité d’enregistrement de fichier pour récupérer le nom d’un fichier à enregistrer.

A Save As dialog box showing the location to save the file.

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

// Configure save file dialog box
Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
dlg.FileName = "Document"; // Default file name
dlg.DefaultExt = ".txt"; // 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;
}
' Configure save file dialog box
Dim dlg As New Microsoft.Win32.SaveFileDialog()
dlg.FileName = "Document" ' Default file name
dlg.DefaultExt = ".txt" ' 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

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

La boîte de dialogue d’impression, illustrée ci-dessous, est utilisée par la fonctionnalité d’impression pour choisir et configurer l’imprimante sur laquelle un utilisateur souhaite imprimer des données.

Screenshot that shows a Print dialog box.

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

// 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
}
' 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

Pour plus d’informations sur la boîte de dialogue Imprimer, consultez System.Windows.Controls.PrintDialog. Pour plus d’informations sur l’impression dans WPF, consultez Vue d’ensemble de l’impression.

Boîtes de dialogue personnalisées

Bien que les boîtes de dialogue communes soient utiles (et doivent être utilisées dans la mesure du possible), elles ne prennent pas en charge les exigences des boîtes de dialogue propres au domaine. Dans ces cas-là, 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 modales et sans mode personnalisées.

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

Cette rubrique montre comment créer Window une implémentation de boîte de dialogue modale classique à l’aide de la Margins boîte de dialogue comme exemple (voir Exemple de boîte de dialogue). La Margins boîte de dialogue s’affiche dans la figure suivante.

A Margins dialog box with fields to define left margin, top margin, right margin, and bottom margin.

Configuration d’une boîte de dialogue modale

L’interface utilisateur pour une boîte de dialogue classique comprend les éléments suivants :

  • Les différents contrôles nécessaires pour recueillir les données souhaitées

  • Bouton OK que les utilisateurs cliquent pour fermer la boîte de dialogue, revenir à la fonction et poursuivre le traitement.

  • Bouton Annuler que les utilisateurs cliquent pour fermer la boîte de dialogue et empêcher la fonction de poursuivre le traitement.

  • Bouton Fermer dans la barre de titre.

  • icône ;

  • Réduisez, agrandissez et restaurez les boutons.

  • Menu système pour réduire, agrandir, restaurer et fermer la boîte de dialogue.

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

  • La possibilité d’être redimensionnée dans la mesure du possible pour empêcher la boîte de dialogue d’être trop petite et de fournir à l’utilisateur une taille par défaut utile. Cela nécessite que vous définissiez à la fois les dimensions par défaut et minimales.

  • Touche Échap en tant que raccourci clavier qui entraîne l’appui du bouton Annuler . Pour ce faire, définissez la IsCancel propriété du bouton Annuler sur true.

  • Touche ENTRÉE (ou RETOUR) en tant que raccourci clavier qui entraîne l’appui du bouton OK . Pour ce faire, définissez la IsDefault propriété du bouton trueOK.

Le code suivant illustre cette configuration.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://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>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace SDKSample
{
    public partial class MarginsDialogBox : Window
    {
        public MarginsDialogBox()
        {
            InitializeComponent();
        }
    }
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Input

Namespace SDKSample
    Public Class MarginsDialogBox
        Inherits Window

        Public Sub New()
            Me.InitializeComponent()
        End Sub
    End Class
End Namespace

L’expérience utilisateur pour une boîte de dialogue s’étend également à la barre de menus de la fenêtre qui ouvre la boîte de dialogue. Quand un élément de menu exécute une fonction qui nécessite une interaction utilisateur par l’intermédiaire d’une boîte de dialogue pour que la fonction puisse se poursuivre, l’élément de menu de la fonction a des points de suspension dans son en-tête, comme illustré ici.

<!--Main Window-->
<MenuItem Name="formatMarginsMenuItem" Header="_Margins..." Click="formatMarginsMenuItem_Click" />

Quand un élément de menu exécute une fonction qui affiche une boîte de dialogue qui ne nécessite pas d’intervention de l’utilisateur, par exemple une boîte de dialogue À propos, les points de suspension ne sont pas nécessaires.

Ouverture d’une boîte de dialogue modale

Une boîte de dialogue apparaît généralement quand un utilisateur sélectionne un élément de menu pour exécuter une fonction propre à un domaine, par exemple pour définir les marges d’un document dans un traitement de texte. Afficher une fenêtre sous forme de boîte de dialogue s’apparente à afficher une fenêtre normale, bien que cela nécessite une configuration supplémentaire propre à la boîte de dialogue. L’ensemble du processus d’instanciation, de configuration et d’ouverture d’une boîte de dialogue est illustré dans le code suivant.

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;

namespace SDKSample
{
    public partial class MainWindow : Window
    {
        bool needsToBeSaved;
        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();
        }
    }
}
Imports System.ComponentModel
Imports System.Windows
Imports System.Windows.Controls
Imports Microsoft.Win32

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

Ici, le code transmet les informations par défaut (marges actuelles) à la boîte de dialogue. Elle définit également la Window.Owner propriété 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 de la fenêtre qui sont communs à toutes les boîtes de dialogue (consultez Vue d’ensemble de WPF pour plus d’informations).

Remarque

Vous devez fournir un propriétaire pour prendre en charge l’automatisation de l’interface utilisateur pour les boîtes de dialogue (voir Vue d’ensemble d’UI Automation).

Une fois la boîte de dialogue configurée, elle s’affiche modalement en appelant la ShowDialog méthode.

Validation des données fournies par l’utilisateur

Quand 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 vérifier 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.

  • D’un point de vue propre au domaine, la validation des données empêche que des données erronées soient traité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 lesquelles des données entrées ne sont pas valides.

  • Du point de vue des performances, la validation des données dans une application multicouche peut réduire le nombre d’allers-retours entre le client et les couches Application, en particulier quand l’application est composée de services web ou de bases de données basées sur serveur.

Pour valider un contrôle lié 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 qui dérive de ValidationRule. L’exemple suivant montre une règle de validation, MarginValidationRulequi case activée qu’une valeur liée est un Double et se trouve dans une plage spécifiée.

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

Dans ce code, la logique de validation d’une règle de validation est implémentée en remplaçant la Validate méthode, qui valide les données et retourne une valeur appropriée ValidationResult.

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

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://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>

    <!-- Left Margin -->
    <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>
  </Grid >
</Window>

Une fois la règle de validation associée, WPF l’applique automatiquement lorsque les données sont entrées dans le contrôle lié. Lorsqu’un contrôle contient des données non valides, WPF affiche une bordure rouge autour du contrôle non valide, comme illustré dans la figure suivante.

A Margins dialog box with a red border around the invalid left margin value.

WPF ne limite pas un utilisateur au contrôle non valide tant qu’il n’a pas entré de données valides. Il s’agit d’un bon comportement pour une boîte de dialogue. En effet, un utilisateur doit pouvoir naviguer librement entre les contrôles d’une boîte de dialogue, que les données soient valides ou non. Toutefois, cela signifie qu’un utilisateur peut entrer des données non valides, puis appuyer sur le bouton OK. Pour cette raison, votre code doit également valider tous les contrôles d’une boîte de dialogue lorsque le bouton OK est enfoncé en gérant l’événement Click .

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

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;
        }
    }
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Input

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

Ce code énumère tous les objets de dépendance sur une fenêtre et, le cas échéant, non valides (comme retourné par GetHasError, le contrôle non valide obtient le focus, la IsValid méthode retourne falseet la fenêtre est considérée comme non valide.

Une fois qu’une boîte de dialogue est valide, elle peut être fermée et retourner un résultat en toute sécurité. Dans le cadre du processus de retour, elle doit retourner un résultat à la fonction appelante.

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

L’ouverture d’une boîte de dialogue à l’aide ShowDialog d’une méthode est fondamentalement semblable à l’appel d’une méthode : code qui a ouvert la boîte de dialogue à l’aide ShowDialog d’attentes jusqu’à ce qu’elle ShowDialog soit retournée. Quand ShowDialog elle est retournée, le code qui l’a appelé doit décider s’il faut continuer à traiter ou arrêter le traitement, en fonction de l’appui de l’utilisateur 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 en tant que Boolean valeur retournée par la ShowDialog méthode.

Lorsque le bouton OK est cliqué, ShowDialog retournez true. Pour ce faire, définissez la DialogResult propriété de la boîte de dialogue lorsque le bouton OK est cliqué.

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace SDKSample
{
    public partial class MarginsDialogBox : Window
    {

        void okButton_Click(object sender, RoutedEventArgs e)
        {
            this.DialogResult = true;
        }
    }
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Input

Namespace SDKSample
    Public Class MarginsDialogBox
        Inherits Window

        Private Sub okButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            ' Dialog box accepted
            MyBase.DialogResult = New Nullable(Of Boolean)(True)
        End Sub
    End Class
End Namespace

Notez que la définition de la propriété entraîne également la fermeture automatique de la DialogResult fenêtre, ce qui réduit la nécessité d’appeler Closeexplicitement .

Lorsque le bouton Annuler est cliqué, ShowDialog doit retourner false, ce qui nécessite également la définition de la DialogResult propriété.

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace SDKSample
{
    public partial class MarginsDialogBox : Window
    {

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

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

Lorsque la propriété d’un IsCancel bouton est définie true et que l’utilisateur appuie sur le bouton Annuler ou la touche Échap, DialogResult elle est automatiquement définie falsesur . Le balisage suivant 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 false automatiquement lorsqu’un utilisateur appuie sur le bouton Fermer dans la barre de titre ou 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

Quand DialogResult une boîte de dialogue est définie par une boîte de dialogue, la fonction qui l’a ouverte peut obtenir le résultat de la boîte de dialogue en inspectant la DialogResult propriété quand elle ShowDialog est retournée.

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;

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;
            }
        }
    }
}
Imports System.ComponentModel
Imports System.Windows
Imports System.Windows.Controls
Imports Microsoft.Win32

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

Si le résultat de la boîte de dialogue est true, la fonction considère cela comme un indice signifiant qu’il faut récupérer et traiter les données fournies par l’utilisateur.

Remarque

Une ShowDialog fois retourné, une boîte de dialogue ne peut pas être rouverte. Au lieu de cela, vous devez 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 sans mode

Une boîte de dialogue non modale, telle que la boîte de dialogue Rechercher affichée ci-dessous, a la même apparence fondamentale que la boîte de dialogue modale.

Screenshot that shows a Find dialog box.

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

Ouverture d’une boîte de dialogue sans mode

Une boîte de dialogue sans mode est ouverte en appelant la Show méthode.

<!--Main Window-->
<MenuItem Name="editFindMenuItem" Header="_Find" InputGestureText="Ctrl+F" Click="editFindMenuItem_Click" />
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;

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();
        }
    }
}
Imports System.ComponentModel
Imports System.Windows
Imports System.Windows.Controls
Imports Microsoft.Win32

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

Contrairement ShowDialogà , Show retourne immédiatement. Ainsi, la fenêtre appelante ne peut pas savoir quand la boîte de dialogue non modale est fermée, et ne sait pas quand vérifier le résultat d’une boîte de dialogue ou obtenir des données à partir de la boîte de dialogue pour un traitement ultérieur. Au lieu de cela, la boîte de dialogue doit créer un autre moyen pour retourner des données à la fenêtre appelante en vue de leur traitement.

Traitement des données retournées à partir d’une boîte de dialogue sans mode

Dans cet exemple, il FindDialogBox peut retourner un ou plusieurs résultats de recherche dans la fenêtre principale, en fonction du texte recherché sans fréquence spécifique. Comme avec une boîte de dialogue modale, une boîte de dialogue non modale peut retourner des résultats à l’aide de propriétés. Toutefois, la fenêtre propriétaire de la boîte de dialogue doit savoir quand vérifier ces propriétés. L’une des solutions consiste à ce que la boîte de dialogue implémente un événement déclenché chaque fois que le texte est trouvé. FindDialogBox implémente à TextFoundEvent cet effet, ce qui nécessite d’abord un délégué.

using System;

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

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

using System;
using System.Windows;
using System.Windows.Controls;
using System.Text.RegularExpressions;

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

    }
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Text.RegularExpressions

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

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

using System;
using System.Windows;
using System.Windows.Controls;
using System.Text.RegularExpressions;

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();
        }
    }
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Text.RegularExpressions

Namespace SDKSample

    Public Class FindDialogBox
        Inherits Window



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

    End Class
End Namespace

La fenêtre propriétaire doit ensuite s’inscrire pour cet événement et le gérer.

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Win32;

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();
        }
    }
}
Imports System.ComponentModel
Imports System.Windows
Imports System.Windows.Controls
Imports Microsoft.Win32

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

Fermeture d’une boîte de dialogue sans mode

Comme DialogResult il n’est pas nécessaire de définir un dialogue sans mode, vous pouvez fermer une boîte de dialogue sans mode à l’aide de mécanismes fournis par le système, y compris les éléments suivants :

  • Un clic sur le bouton Fermer dans la barre de titre

  • Un appui sur Alt+F4

  • Choisissez Fermer dans le menu Système .

Vous pouvez également appeler Close votre code lorsque le bouton Fermer est cliqué.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Text.RegularExpressions;

namespace SDKSample
{
    public partial class FindDialogBox : Window
    {

        void closeButton_Click(object sender, RoutedEventArgs e)
        {
            // Close dialog box
            this.Close();
        }
    }
}
Imports System.Windows
Imports System.Windows.Controls
Imports System.Text.RegularExpressions

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

Voir aussi