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.
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 static
Show 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.
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.
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.
Dialoogvenster Afdrukken
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.
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.
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.
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 false
en 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 ShowDialogtrue
retourneren. 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 ShowDialogfalse
retourneren. 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 false
is, 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.
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
.NET Desktop feedback