Delen via


Overzicht van dialoogvensters

Zelfstandige toepassingen hebben doorgaans een hoofdvenster waarin zowel de belangrijkste gegevens worden weergegeven waarop de toepassing werkt en de functionaliteit beschikbaar maakt om die gegevens te verwerken via gebruikersinterfacemechanismen zoals menubalken, toolbalken en statusbalken. Een niet-triviale toepassing kan ook extra vensters weergeven om het volgende te doen:

  • Specifieke informatie weergeven aan gebruikers.

  • Verzamel informatie van gebruikers.

  • Zowel informatie weergeven als verzamelen.

Deze typen vensters worden dialoogvenstersgenoemd en er zijn twee typen: modaal en modusloos.

Een modaal dialoogvenster wordt weergegeven door een functie wanneer de functie aanvullende gegevens van een gebruiker nodig heeft om door te gaan. Omdat de functie afhankelijk is van het modale dialoogvenster om gegevens te verzamelen, voorkomt het modale dialoogvenster ook dat een gebruiker andere vensters in de toepassing activeert terwijl deze geopend blijft. In de meeste gevallen kan een gebruiker in een modaal dialoogvenster signaleren wanneer hij klaar is door op een OK- of Annuleren- knop te drukken. Als u op de knop OK drukt, wordt aangegeven dat een gebruiker gegevens heeft ingevoerd en dat de functie met die gegevens verder moet worden verwerkt. Als u op de knop Annuleren drukt, wordt aangegeven dat een gebruiker de functie helemaal niet meer wil uitvoeren. De meest voorkomende voorbeelden van modale dialoogvensters worden weergegeven om gegevens te openen, op te slaan en af te drukken.

Een modeless dialoogvenster voorkomt daarentegen niet dat een gebruiker andere vensters activeert terwijl het geopend is. Als een gebruiker bijvoorbeeld exemplaren van een bepaald woord in een document wil vinden, wordt in een hoofdvenster vaak een dialoogvenster geopend om een gebruiker te vragen naar welk woord hij of zij zoekt. Omdat het zoeken van een woord niet verhindert dat een gebruiker het document bewerkt, hoeft het dialoogvenster echter niet modaal te zijn. Een modusloos dialoogvenster bevat ten minste een knop Sluiten om het dialoogvenster te sluiten en kan extra knoppen bevatten om specifieke functies uit te voeren, zoals een knop Zoek volgende om het volgende woord te vinden dat overeenkomt met de zoekcriteria van een woordzoekopdracht.

Met Windows Presentation Foundation (WPF) kunt u verschillende typen dialoogvensters maken, waaronder berichtvakken, algemene dialoogvensters en aangepaste dialoogvensters. In dit onderwerp wordt elk onderwerp besproken en het dialoogvenstervoorbeeld bevat overeenkomende voorbeelden.

Berichtvakken

Een berichtvak is een dialoogvenster dat kan worden gebruikt om tekstuele informatie weer te geven en gebruikers in staat te stellen beslissingen te nemen met knoppen. In de volgende afbeelding ziet u een berichtvak waarin tekstinformatie wordt weergegeven, een vraag wordt gesteld en de gebruiker drie knoppen heeft om de vraag te beantwoorden.

Een dialoogvenster van een tekstverwerker waarin u wordt gevraagd of u de wijzigingen in het document wilt opslaan voordat de applicatie wordt gesloten.

Als u een berichtvak wilt maken, gebruikt u de klasse MessageBox. MessageBox kunt u de tekst, titel, pictogram en knoppen van het berichtvak configureren met behulp van code zoals hieronder.

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

Als u een berichtvak wilt weergeven, roept u de methode staticShow aan, zoals wordt weergegeven in de volgende code.

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

Wanneer code met een berichtvak de beslissing van de gebruiker moet detecteren en verwerken (welke knop is ingedrukt), kan de code het resultaat van het berichtvak inspecteren, zoals wordt weergegeven in de volgende code.

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

Zie MessageBox, MessageBox Sampleen Dialog Box Samplevoor meer informatie over het gebruik van berichtvakken.

Hoewel MessageBox een eenvoudige gebruikerservaring in het dialoogvenster kan bieden, is het voordeel van het gebruik van MessageBox dat het enige type venster is dat kan worden weergegeven door toepassingen die worden uitgevoerd in een gedeeltelijke vertrouwensbeveiligings sandbox (zie Security), zoals XAML-browsertoepassingen (XBAPs).

In de meeste dialoogvensters worden complexere gegevens verzameld en weergegeven dan het resultaat van een berichtvak, waaronder tekst, selectie (selectievakjes), elkaar uitsluitende selectie (radioknoppen) en lijstselectie (keuzelijsten, invoervak met keuzelijst, vervolgkeuzelijsten). Hiervoor biedt Windows Presentation Foundation (WPF) verschillende algemene dialoogvensters en kunt u uw eigen dialoogvensters maken, hoewel het gebruik van beide beperkt is tot toepassingen die met volledig vertrouwen worden uitgevoerd.

Algemene dialoogvensters

Windows implementeert diverse herbruikbare dialoogvensters die gebruikelijk zijn voor alle toepassingen, waaronder dialoogvensters voor het openen van bestanden, het opslaan van bestanden en het afdrukken. Aangezien deze dialoogvensters door het besturingssysteem worden geïmplementeerd, kunnen ze worden gedeeld tussen alle toepassingen die worden uitgevoerd op het besturingssysteem, wat de consistentie van de gebruikerservaring helpt; wanneer gebruikers bekend zijn met het gebruik van een dialoogvenster van een besturingssysteem in één toepassing, hoeven ze niet te leren hoe ze dat dialoogvenster in andere toepassingen kunnen gebruiken. Omdat deze dialoogvensters beschikbaar zijn voor alle toepassingen en omdat ze een consistente gebruikerservaring bieden, worden ze ook wel algemene dialoogvenstersgenoemd.

Windows Presentation Foundation (WPF) bevat het geopende bestand, het opslaan van bestanden en het afdrukken van algemene dialoogvensters en toont ze als beheerde klassen die u kunt gebruiken in zelfstandige toepassingen. Dit onderwerp bevat een kort overzicht van elk onderwerp.

Dialoogvenster Bestand openen

Het dialoogvenster Bestand openen, weergegeven in de volgende afbeelding, wordt gebruikt door de functionaliteit voor het openen van bestanden om de naam van een bestand op te halen dat moet worden geopend.

dialoogvenster Openen met de locatie waar het bestand moet worden opgehaald.

Het algemene dialoogvenster Bestand openen wordt geïmplementeerd als de OpenFileDialog-klasse en bevindt zich in de Microsoft.Win32 naamruimte. De volgende code laat zien hoe u er een maakt, configureert en weergeeft en hoe u het resultaat verwerkt.

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

Zie Microsoft.Win32.OpenFileDialogvoor meer informatie over het dialoogvenster Bestand openen.

Notitie

OpenFileDialog kan worden gebruikt om bestandsnamen veilig op te halen door toepassingen die worden uitgevoerd met gedeeltelijke vertrouwensrelatie (zie Security).

Dialoogvenster Bestand opslaan

Het dialoogvenster Bestand opslaan, weergegeven in de volgende afbeelding, wordt gebruikt door de functionaliteit voor het opslaan van bestanden om de naam van een bestand op te halen dat moet worden opgeslagen.

dialoogvenster Opslaan als met de locatie waarop het bestand moet worden opgeslagen.

Het algemene dialoogvenster Bestand opslaan wordt geïmplementeerd als de klasse SaveFileDialog en bevindt zich in de Microsoft.Win32 naamruimte. De volgende code laat zien hoe u er een maakt, configureert en weergeeft en hoe u het resultaat verwerkt.

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

Zie Microsoft.Win32.SaveFileDialogvoor meer informatie over het dialoogvenster Bestand opslaan.

Het dialoogvenster Afdrukken, weergegeven in de volgende afbeelding, wordt gebruikt door de afdrukfunctionaliteit te gebruiken om de printer te kiezen en te configureren waarnaar een gebruiker gegevens wil afdrukken.

Schermopname die een dialoogvenster voor afdrukken laat zien.

Het algemene afdrukdialoogvenster wordt geïmplementeerd als de klasse PrintDialog en bevindt zich in de System.Windows.Controls naamruimte. De volgende code laat zien hoe u er een maakt, configureert en weergeeft.

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

Zie System.Windows.Controls.PrintDialogvoor meer informatie over het dialoogvenster Afdrukken. Zie Print Overviewvoor een gedetailleerde bespreking van afdrukken in WPF.

Aangepaste dialoogvensters

Hoewel algemene dialoogvensters nuttig zijn en indien mogelijk moeten worden gebruikt, bieden ze geen ondersteuning voor de vereisten van domeinspecifieke dialoogvensters. In dergelijke gevallen moet u uw eigen dialoogvensters maken. Zoals we zien, is een dialoogvenster een venster met speciaal gedrag. Window implementeert dit gedrag en dus gebruikt u Window om aangepaste modale en niet-modale dialoogvensters te maken.

Een modaal aangepast dialoogvenster maken

In dit onderwerp wordt beschreven hoe u Window kunt gebruiken om een typische modale dialoogvenster-implementatie te maken met behulp van het dialoogvenster Margins als voorbeeld (zie dialoogvenstervoorbeeld). Het dialoogvenster Margins wordt weergegeven in de volgende afbeelding.

dialoogvenster Marges met velden om linkermarge, bovenmarge, rechtermarge en ondermarge te definiëren.

Een modaal dialoogvenster configureren

De gebruikersinterface voor een standaarddialoogvenster bevat het volgende:

  • De verschillende besturingselementen die nodig zijn om de gewenste gegevens te verzamelen.

  • Een knop OK waarop gebruikers klikken om het dialoogvenster te sluiten, terug te keren naar de functie en door te gaan met verwerken.

  • Een Annuleren knop waarop gebruikers klikken om het dialoogvenster te sluiten en te voorkomen dat de functie verder wordt verwerkt.

  • Een sluitknop in de titelbalk.

  • Een pictogram.

  • minimaliseren, maximaliseren en knoppen herstellen.

  • Een menu System om het dialoogvenster te minimaliseren, maximaliseren, herstellen en sluiten.

  • Een positie boven en in het midden van het venster dat het dialoogvenster heeft geopend.

  • De mogelijkheid om het formaat waar mogelijk te wijzigen om te voorkomen dat het dialoogvenster te klein is en om de gebruiker een nuttige standaardgrootte te bieden. Hiervoor moet u zowel de standaard- als een minimale dimensie instellen.

  • De ESC-toets als sneltoets die ervoor zorgt dat de knop Annuleren wordt ingedrukt. U doet dit door de eigenschap IsCancel van de knop Annuleren in te stellen op true.

  • De toets ENTER (of RETURN) als sneltoets waardoor de knop OK wordt ingedrukt. U doet dit door de eigenschap IsDefault van de OK-knop in te stellen true.

De volgende code demonstreert deze configuratie.

<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

De gebruikerservaring voor een dialoogvenster wordt ook uitgebreid naar de menubalk van het venster dat het dialoogvenster opent. Wanneer een menu-item een functie uitvoert waarvoor gebruikersinteractie via een dialoogvenster is vereist voordat de functie kan worden voortgezet, bevat het menu-item voor de functie een beletselteken in de koptekst, zoals hier wordt weergegeven.

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

Wanneer een menu-item een functie uitvoert waarmee een dialoogvenster wordt weergegeven waarvoor geen gebruikersinteractie is vereist, zoals een dialoogvenster Info, is er geen beletselteken vereist.

Een modaal dialoogvenster openen

Een dialoogvenster wordt meestal weergegeven als gevolg van een gebruiker die een menu-item selecteert om een domeinspecifieke functie uit te voeren, zoals het instellen van de marges van een document in een tekstverwerker. Het weergeven van een venster als een dialoogvenster is vergelijkbaar met het weergeven van een normaal venster, hoewel er extra dialoogvensterspecifieke configuratie is vereist. Het hele proces van het instantiëren, configureren en openen van een dialoogvenster wordt weergegeven in de volgende code.

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

Hier geeft de code standaardinformatie (de huidige marges) door aan het dialoogvenster. Ook wordt de eigenschap Window.Owner ingesteld met een verwijzing naar het venster waarin het dialoogvenster wordt weergegeven. Over het algemeen moet u de eigenaar voor een dialoogvenster altijd instellen om statusgerelateerde gedrag voor vensters op te geven dat gebruikelijk is voor alle dialoogvensters (zie WPF Windows Overview voor meer informatie).

Notitie

U moet een eigenaar opgeven om automatisering van gebruikersinterfaces (UI) te ondersteunen voor dialoogvensters (zie UI Automation Overview).

Nadat het dialoogvenster is geconfigureerd, wordt het modaal weergegeven door de methode ShowDialog aan te roepen.

Door de gebruiker verstrekte gegevens valideren

Wanneer een dialoogvenster wordt geopend en de gebruiker de vereiste gegevens verstrekt, is een dialoogvenster verantwoordelijk om ervoor te zorgen dat de opgegeven gegevens om de volgende redenen geldig zijn:

  • Vanuit beveiligingsperspectief moet alle invoer worden gevalideerd.

  • Vanuit een domeinspecifiek perspectief voorkomt gegevensvalidatie dat onjuiste gegevens worden verwerkt door de code, waardoor er mogelijk uitzonderingen kunnen ontstaan.

  • Vanuit een gebruikerservaringsperspectief kan een dialoogvenster gebruikers helpen door hen te laten zien welke gegevens ze hebben ingevoerd, ongeldig is.

  • Vanuit het oogpunt van prestaties kan gegevensvalidatie in een toepassing met meerdere lagen het aantal retouren tussen de client en de toepassingslagen verminderen, met name wanneer de toepassing bestaat uit webservices of op servers gebaseerde databases.

Als u een afhankelijk besturingselement in WPF wilt valideren, moet u een validatieregel definiëren en deze koppelen aan de binding. Een validatieregel is een aangepaste klasse die is afgeleid van ValidationRule. In het volgende voorbeeld ziet u een validatieregel, MarginValidationRule, waarmee wordt gecontroleerd of een afhankelijke waarde een Double is en zich binnen een opgegeven bereik bevindt.

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

In deze code wordt de validatielogica van een validatieregel geïmplementeerd door de Validate methode te overschrijven, waarmee de gegevens worden gevalideerd en een geschikte ValidationResultwordt geretourneerd.

Als u de validatieregel wilt koppelen aan het gebonden besturingselement, gebruikt u de volgende markup.

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

Zodra de validatieregel is gekoppeld, past WPF deze automatisch toe wanneer gegevens in het gebonden besturingselement worden ingevoerd. Wanneer een besturingselement ongeldige gegevens bevat, geeft WPF een rode rand rond het ongeldige besturingselement weer, zoals wordt weergegeven in de volgende afbeelding.

Marges-dialoogvenster met een rode rand rond de ongeldige waarde van de linkermarge.

WPF beperkt een gebruiker niet in een ongeldig invoerveld totdat er geldige gegevens zijn ingevoerd. Dit is goed gedrag voor een dialoogvenster; een gebruiker moet vrij kunnen navigeren door de besturingselementen in een dialoogvenster, ongeacht of gegevens geldig zijn. Dit betekent echter dat een gebruiker ongeldige gegevens kan invoeren en op de knop OK drukt. Daarom moet uw code ook alle besturingselementen in een dialoogvenster valideren wanneer de knop OK wordt ingedrukt, door het Click-event af te handelen.

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

Met deze code worden alle afhankelijkheidsobjecten in een venster opgesomd en, als deze ongeldig zijn (zoals geretourneerd door GetHasError, krijgt het ongeldige besturingselement de focus, retourneert de IsValid methode falseen wordt het venster als ongeldig beschouwd.

Zodra een dialoogvenster geldig is, kan het veilig worden gesloten en geretourneerd. Als onderdeel van het retourproces moet het een resultaat retourneren aan de aanroepende functie.

Het resultaat van het modale dialoogvenster instellen

Het openen van een dialoogvenster met behulp van ShowDialog lijkt op het aanroepen van een methode: de code die het dialoogvenster heeft geopend met ShowDialog wacht totdat ShowDialog retourneert. Wanneer ShowDialog retourneert, moet de code waarmee deze wordt aangeroepen, bepalen of de verwerking moet worden voortgezet of gestopt op basis van of de gebruiker op de knop OK of de knop Annuleren ingedrukt heeft. Om deze beslissing te vergemakkelijken, moet het dialoogvenster de keuze van de gebruiker retourneren als een Boolean waarde die wordt geretourneerd door de ShowDialog methode.

Wanneer op de knop OK wordt geklikt, moet ShowDialogtrueretourneren. Dit wordt bereikt door de eigenschap DialogResult van het dialoogvenster in te stellen wanneer op de knop OK wordt geklikt.

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

Let op dat als u de eigenschap DialogResult instelt, het venster ook automatisch wordt gesloten, waardoor het niet nodig is om expliciet Closeaan te roepen.

Wanneer op de knop Annuleren wordt geklikt, moet ShowDialogfalseretourneren. Hiervoor moet ook de eigenschap DialogResult worden ingesteld.

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

Wanneer de eigenschap IsCancel van een knop is ingesteld op true en de gebruiker op de knop Annuleren of op esc drukt, wordt DialogResult automatisch ingesteld op false. De volgende markeringen hebben hetzelfde effect als de voorgaande code, zonder dat de Click gebeurtenis hoeft te worden verwerkt.

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

Een dialoogvenster retourneert automatisch false wanneer een gebruiker op de knop sluiten in de titelbalk drukt of de menuopdracht sluiten kiest in het menu System.

Gegevens verwerken die worden geretourneerd vanuit een modaal dialoogvenster

Wanneer DialogResult is ingesteld door een dialoogvenster, kan de geopende functie het resultaat van het dialoogvenster krijgen door de eigenschap DialogResult te controleren wanneer ShowDialog retourneert.

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

Als het dialoogvensterresultaat is true, gebruikt de functie deze als aanwijzing om de gegevens op te halen en te verwerken die door de gebruiker worden geleverd.

Notitie

Nadat ShowDialog is geretourneerd, kan een dialoogvenster niet opnieuw worden geopend. In plaats daarvan moet u een nieuw exemplaar maken.

Als het dialoogvensterresultaat falseis, moet de functie de verwerking op de juiste manier beëindigen.

Een modelloos aangepast dialoogvenster maken

Een modeless dialoogvenster, zoals het Zoek-dialoogvenster in de volgende afbeelding, heeft hetzelfde fundamentele uiterlijk als het modale dialoogvenster.

Schermopname met het dialoogvenster Zoeken.

Het gedrag is echter iets anders, zoals beschreven in de volgende secties.

Een niet-modusafhankelijk dialoogvenster openen

Er wordt een modusloos dialoogvenster geopend door de methode Show aan te roepen.

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

In tegenstelling tot ShowDialogretourneert Show onmiddellijk. Daarom kan het oproepvenster niet zien wanneer het modusloze dialoogvenster is gesloten en weet niet wanneer er moet worden gecontroleerd op een dialoogvensterresultaat of gegevens op te halen uit het dialoogvenster voor verdere verwerking. In plaats daarvan moet het dialoogvenster een alternatieve manier maken om gegevens te retourneren naar het oproepvenster voor verwerking.

Gegevens verwerken die worden geretourneerd vanuit een modeless dialoogvenster

In dit voorbeeld kan de FindDialogBox een of meer resultaten retourneren naar het hoofdvenster, afhankelijk van de tekst die wordt gezocht zonder een specifieke frequentie. Net als bij een modaal dialoogvenster kan een niet-modaal dialoogvenster resultaten retourneren met behulp van eigenschappen. Het venster dat eigenaar is van het dialoogvenster moet echter weten wanneer deze eigenschappen moeten worden gecontroleerd. Een manier om dit in te schakelen, is door het dialoogvenster een gebeurtenis te implementeren die wordt gegenereerd wanneer tekst wordt gevonden. FindDialogBox implementeert de TextFoundEvent voor dit doel, waarvoor eerst een gemachtigde is vereist.

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

Met behulp van de TextFoundEventHandler gedelegeerde implementeert FindDialogBox de 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

Daarom kan Find de gebeurtenis genereren wanneer een zoekresultaat wordt gevonden.

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

Het eigenaarsvenster moet zich vervolgens registreren bij het evenement en deze gebeurtenis afhandelen.

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

Een niet-modale dialoogvenster sluiten

Omdat DialogResult niet hoeft te worden ingesteld, kan een modusloos dialoogvenster worden gesloten met behulp van systeemmechanismen, waaronder de volgende:

  • Klik op de knop Sluiten in de titelbalk.

  • Druk op Alt+F4.

  • Kies sluiten in het menu System.

U kunt ook Close aanroepen wanneer op de knop sluiten wordt geklikt.

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

Zie ook