Übersicht über Dialogfelder
Eigenständige Anwendungen haben in der Regel ein Hauptfenster, das sowohl die Nutzdaten anzeigt, mit denen die Anwendung arbeitet, als auch die Funktionen zum Verarbeiten dieser Daten über UI-Mechanismen (User Interface, Benutzeroberfläche) wie Menüleisten, Symbolleisten und Statusleisten verfügbar macht. Eine nicht triviale Anwendung kann auch zusätzliche Fenster anzeigen, um Folgendes auszuführen:
Spezifische Informationen für Benutzer anzeigen.
Informationen von Benutzern erfassen.
Informationen sowohl anzeigen als auch erfassen.
Diese Fenstertypen werden als Dialogfelder bezeichnet, von denen es zwei Arten gibt: modale und nicht modale Dialogfelder.
Ein modales Dialogfeld wird von einer Funktion angezeigt, wenn die Funktion zusätzliche Daten von einem Benutzer benötigt, um den Vorgang fortsetzen zu können. Da die Funktion beim Erfassen der Daten vom modalen Dialogfeld abhängig ist, verhindert das modale Dialogfeld auch, dass der Benutzer andere Fenster in der Anwendung aktiviert, während das Dialogfeld geöffnet bleibt. In den meisten Fällen kann ein Benutzer in einem modalen Dialogfeld angeben, wann er es nicht mehr benötigt, indem er auf die Schaltfläche OK oder auf Abbrechen klickt. Durch einen Klick auf die Schaltfläche OK wird angezeigt, dass ein Benutzer Daten eingegeben hat und möchte, dass die Funktion mit der Verarbeitung dieser Daten fortfährt. Durch einen Klick auf die Schaltfläche Abbrechen wird angezeigt, dass ein Benutzer möchte, dass die Funktion die Ausführung komplett abbricht. Die häufigsten Beispiele für modale Dialogfelder sind das Öffnen, Speichern und Drucken von Daten.
Ein nicht modales Dialogfeld hingegen verhindert nicht, dass ein Benutzer andere Fenster aktiviert, so lange es geöffnet ist. Wenn ein Benutzer z. B. Vorkommen eines bestimmten Worts in einem Dokument finden möchte, wird in einem Hauptfenster oft ein Dialogfeld geöffnet, um den Benutzer zu fragen, nach welchem Wort er sucht. Da die Suche nach einem Wort einen Benutzer aber nicht an der Bearbeitung des Dokuments hindert, muss das Dialogfeld nicht unbedingt modal sein. Ein nicht modales Dialogfeld enthält mindestens die Schaltfläche Schließen, um das Dialogfeld zu schließen, und kann weitere Schaltflächen enthalten, um bestimmte Funktionen auszuführen, etwa die Schaltfläche Weitersuchen, um das nächste Wort zu suchen, das den Suchkriterien einer Wortsuche entspricht.
Mit WPF (Windows Presentation Foundation) können Sie mehrere Typen von Dialogfeldern erstellen. Dazu zählen Meldungsfelder, Standarddialogfelder und benutzerdefinierte Dialogfelder. In diesem Thema wird jeder Typ erläutert, und das Dialogfeldbeispiel stellt entsprechende Beispiele bereit.
Meldungsfelder
Ein Meldungsfeld ist ein Dialogfeld, mit dem Textinformationen angezeigt werden können und mit dem Benutzer mithilfe von Schaltflächen Entscheidungen treffen können. In der folgenden Abbildung ist ein Meldungsfeld dargestellt, in dem Textinformationen angezeigt werden, eine Frage gestellt wird und der Benutzer mithilfe von drei Schaltflächen die Frage beantworten kann.
Um ein Meldungsfeld zu erstellen, verwenden Sie die MessageBox-Klasse. Mit MessageBox können Sie den Text, den Titel, das Symbol und die Schaltflächen im Meldungsfeld konfigurieren, indem Sie Code wie den folgenden verwenden.
// 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
Zum Anzeigen eines Meldungsfelds rufen Sie die static
Show-Methode auf, wie im folgenden Code veranschaulicht.
// Display message box
MessageBox.Show(messageBoxText, caption, button, icon);
' Display message box
MessageBox.Show(messageBoxText, caption, button, icon)
Wenn Code, der ein Meldungsfeld anzeigt, die Entscheidung des Benutzers (welche Schaltfläche angeklickt wurde) erkennen und verarbeiten muss, kann der Code das Ergebnis des Meldungsfelds überprüfen, wie im folgenden Code gezeigt.
// 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
Weitere Informationen zur Verwendung von Nachrichtenfeldern finden Sie unter MessageBox, MessageBox-Beispiel und Dialogfeldbeispiel.
Zwar bietet MessageBox bereits eine einfache Dialogfeld-Benutzeroberfläche, der Vorteil der Verwendung von MessageBox liegt jedoch darin, dass es der einzige Fenstertyp ist, der von Anwendungen angezeigt werden kann, die in einer teilweise vertrauenswürdigen Sicherheitssandbox (siehe Sicherheit), ausgeführt werden, etwa XAML-Browseranwendungen (XBAPs).
In den meisten Dialogfeldern werden komplexere Daten angezeigt und gesammelt als im Ergebnis eines Meldungsfelds. Dazu zählen Text, Auswahlmöglichkeiten (Kontrollkästchen), sich gegenseitig ausschließende Auswahlmöglichkeiten (Optionsfelder) und Auswahlmöglichkeiten in einer Liste (Listenfelder, Kombinationsfelder, Dropdown-Listenfelder). Dafür stellt WPF (Windows Presentation Foundation) mehrere Standarddialogfelder zur Verfügung und ermöglicht es Ihnen, eigene Dialogfelder zu erstellen. Allerdings ist die Verwendung beider Typen auf Anwendungen begrenzt, die mit voller Vertrauenswürdigkeit ausgeführt werden.
Standarddialogfelder
Windows implementiert eine Reihe von wiederverwendbaren Dialogfeldern, die für alle Anwendungen gleich sind. Dazu zählen Dialogfelder zum Öffnen und Speichern von Dateien und zum Drucken. Da diese Dialogfelder durch das Betriebssystem implementiert werden, können sie von allen Anwendungen, die unter dem Betriebssystem ausgeführt werden, genutzt werden. Dies trägt zu einer konsistenten Benutzererfahrung bei: Wenn Benutzer mit der Verwendung eines durch das Betriebssystem bereitgestellten Dialogfelds in einer Anwendung vertraut sind, müssen Sie nicht lernen, wie sie dieses Dialogfeld in anderen Anwendungen verwenden. Da diese Dialogfelder allen Anwendungen zur Verfügung stehen und sie zu einer konsistenten Benutzererfahrung beitragen, werden sie als Standarddialogfelder bezeichnet.
WPF (Windows Presentation Foundation) kapselt die Standarddialogfelder zum Öffnen und Speichern von Dateien sowie zum Drucken und stellt sie als verwaltete Klassen für die Verwendung in eigenständigen Anwendungen zur Verfügung. Dieses Thema enthält eine kurze Übersicht über die einzelnen Dialogfelder.
Dialogfeld „Datei öffnen“
Das Dialogfeld „Datei öffnen“, das in der folgenden Abbildung gezeigt wird, wird von Funktionen zum Öffnen von Dateien verwendet, um den Namen einer zu öffnenden Datei abzurufen.
Das Standarddialogfeld „Datei öffnen“ ist als OpenFileDialog-Klasse implementiert und befindet sich im Microsoft.Win32-Namespace. Im folgenden Code wird gezeigt, wie ein solches Dialogfeld erstellt, konfiguriert und angezeigt und wie das Ergebnis verarbeitet wird.
// 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
Weitere Informationen zum Dialogfeld „Datei öffnen“ finden Sie unter Microsoft.Win32.OpenFileDialog.
Hinweis
Mit OpenFileDialog können Dateinamen von Anwendungen, die mit teilweiser Vertrauenswürdigkeit ausgeführt werden, sicher abgerufen werden (siehe Sicherheit).
Datei speichern (Dialogfeld)
Das Dialogfeld „Datei speichern“, das in der folgenden Abbildung gezeigt wird, wird von Funktionen zum Speichern von Dateien verwendet, um den Namen einer zu speichernden Datei abzurufen.
Das Standarddialogfeld „Datei speichern“ ist als SaveFileDialog-Klasse implementiert und befindet sich im Microsoft.Win32-Namespace. Im folgenden Code wird gezeigt, wie ein solches Dialogfeld erstellt, konfiguriert und angezeigt und wie das Ergebnis verarbeitet wird.
// 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
Weitere Informationen zum Dialogfeld „Datei speichern“ finden Sie unter Microsoft.Win32.SaveFileDialog.
Dialogfeld Drucken
Das Dialogfeld „Drucken“, das in der folgenden Abbildung gezeigt wird, wird von Funktionen zum Drucken verwendet, um den Drucker auszuwählen und zu konfigurieren, auf dem der Benutzer Daten ausgeben möchte.
Das Standarddialogfeld „Drucken“ ist als PrintDialog-Klasse implementiert und befindet sich im System.Windows.Controls-Namespace. Im folgenden Code wird gezeigt, wie ein solches Dialogfeld erstellt, konfiguriert und angezeigt wird.
// 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
Weitere Informationen zum Dialogfeld "Datei drucken" finden Sie unter System.Windows.Controls.PrintDialog. Ausführliche Informationen über das Drucken in WPF finden Sie unter Übersicht über das Drucken.
Benutzerdefinierte Dialogfelder
Obwohl Standarddialogfelder hilfreich sind und nach Möglichkeit verwendet werden sollten, unterstützen sie nicht die Anforderungen von domänenspezifischen Dialogfeldern. In diesen Fällen müssen Sie eigene Dialogfelder erstellen. Wie später ersichtlich wird, ist ein Dialogfeld ein Fenster mit besonderen Verhaltensweisen. Window implementiert diese Verhaltensweisen, und Sie verwenden Window, um benutzerdefinierte modale und nicht modale Dialogfelder zu erstellen.
Erstellen eines modalen benutzerdefinierten Dialogfelds
In diesem Thema wird beschrieben, wie Window verwendet wird, um eine typische Implementierung eines modalen Dialogfelds zu erstellen. Das Dialogfeld Margins
dient als Beispiel (siehe Dialogfeldbeispiel). Das Dialogfeld Margins
wird in der folgenden Abbildung gezeigt.
Konfigurieren eines modalen Dialogfelds
Die Benutzeroberfläche für ein normales Dialogfeld enthält Folgendes:
Die verschiedenen Steuerelemente, die zum Erfassen der gewünschten Daten erforderlich sind.
Eine OK-Schaltfläche, auf die Benutzer klicken, um das Dialogfeld zu schließen, zur Funktion zurückzukehren und mit der Verarbeitung fortzufahren.
Eine Abbrechen-Schaltfläche, auf die Benutzer klicken, um das Dialogfeld zu schließen und zu verhindern, dass die Funktion die Verarbeitung fortsetzt.
Eine Schließen-Schaltfläche in der Titelleiste.
Symbol
Schaltflächen zum Minimieren, Maximieren und Wiederherstellen.
Ein Systemmenü zum Minimieren, Maximieren, Wiederherstellen und Schließen des Dialogfelds.
Eine Position mittig oberhalb des Fensters, das das Dialogfeld geöffnet hat.
Die Möglichkeit zum Ändern der Größe, damit das Dialogfeld nicht zu klein ist, und um dem Benutzer eine sinnvolle Standardgröße anzubieten. Dazu ist es erforderlich, dass Sie sowohl die Standard- als auch die Mindestabmessungen festlegen.
Die ESC-TASTE als Tastenkombination, die bewirkt, dass die Schaltfläche Abbrechen gedrückt wird. Dazu legen Sie die Eigenschaft IsCancel der Schaltfläche Abbrechen auf
true
fest.Die EINGABETASTE als Tastenkombination, die das Drücken der Schaltfläche OK bewirkt. Dazu legen Sie die Eigenschaft IsDefault der Schaltfläche OK auf
true
fest.
Im folgenden Code wird diese Konfiguration veranschaulicht.
<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
Die Benutzererfahrung eines Dialogfelds setzt sich auch in der Menüleiste des Fensters fort, das das Dialogfeld öffnet. Wenn ein Menüelement eine Funktion ausführt, die eine Benutzerinteraktion über ein Dialogfeld benötigt, bevor die Funktion fortfahren kann, weist das Menüelement für die Funktion Auslassungszeichen im Header auf, wie nachfolgend gezeigt.
<!--Main Window-->
<MenuItem Name="formatMarginsMenuItem" Header="_Margins..." Click="formatMarginsMenuItem_Click" />
Wenn ein Menüelement eine Funktion ausführt, die ein Dialogfeld anzeigt, das ohne Benutzerinteraktion auskommt, z. B. das Dialogfeld „Info“, werden die Auslassungszeichen nicht benötigt.
Öffnen eines modalen Dialogfelds
Ein Dialogfeld wird üblicherweise als Ergebnis des Vorgangs angezeigt, bei dem ein Benutzer ein Menüelement auswählt, um eine domänenspezifische Funktion auszuführen, z. B. das Festlegen der Ränder eines Dokuments in einem Textverarbeitungsprogramm. Das Anzeigen eines Fensters als Dialogfeld ähnelt dem Anzeigen eines normalen Fensters, benötigt jedoch eine zusätzliche dialogfeldspezifische Konfiguration. Der vollständige Vorgang des Instanziierens, Konfigurierens und Öffnens eines Dialogfelds wird im folgenden Code gezeigt.
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
An dieser Stelle werden vom Code Standardinformationen (die aktuellen Ränder) an das Dialogfeld übergeben. Außerdem wird die Eigenschaft Window.Owner auf einen Verweis auf das Fenster festgelegt, in dem das Dialogfeld angezeigt wird. Im Allgemeinen sollten Sie immer den Besitzer eines Dialogfelds festlegen, um zustandsbezogenes Verhalten von Fenstern bereitzustellen, die für alle Dialogfelder gelten (weitere Informationen finden Sie unter Übersicht über WPF-Fenster).
Hinweis
Sie müssen einen Besitzer angeben, um die UI-Automatisierung (User Interface, Benutzeroberfläche) für Dialogfelder zu unterstützen (siehe dazu Übersicht über die Benutzeroberflächenautomatisierung).
Nachdem das Dialogfeld konfiguriert ist, wird es durch Aufrufen der Methode ShowDialog modal angezeigt.
Überprüfen der vom Benutzer bereitgestellten Daten
Wenn ein Dialogfeld geöffnet wird und der Benutzer die benötigten Daten zur Verfügung stellt, ist ein Dialogfeld aus folgenden Gründen dafür verantwortlich, dass die bereitgestellten Daten gültig sind:
Aus Gründen der Datensicherheit sollten alle Eingaben überprüft werden.
Aus domänenspezifischer Sicht verhindert die Datenvalidierung, dass fehlerhafte Daten vom Code verarbeitet werden, was zum Auslösen von Ausnahmen führen kann.
Aus Gründen der Benutzererfahrung kann ein Dialogfeld dazu beitragen, Benutzern zu helfen, indem ihnen gezeigt wird, welche der von ihnen eingegebenen Daten ungültig sind.
Unter Leistungsaspekten betrachtet, kann die Datenvalidierung in einer Anwendung mit mehreren Ebenen die Anzahl von Roundtrips zwischen der Client- und der Anwendungsebene vermindern, insbesondere, wenn die Anwendung aus Webdiensten oder serverbasierten Datenbanken besteht.
Zum Überprüfen eines gebundenen Steuerelements in WPF müssen Sie eine Validierungsregel angeben und sie der Bindung zuordnen. Eine Validierungsregel ist eine benutzerdefinierte Klasse, die von ValidationRule abgeleitet ist. Im folgenden Beispiel wird die Validierungsregel MarginValidationRule
gezeigt, die überprüft, ob ein gebundener Wert ein Double ist und in einem angegebenen Bereich liegt.
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 diesem Code wird die Validierungsregel durch Außerkraftsetzen der Methode Validate implementiert, die die Daten überprüft und ein entsprechendes ValidationResult zurückgibt.
Um die Validierungsregel dem gebundenen Steuerelement zuzuordnen, wird das folgende Markup verwendet.
<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>
Nachdem die Validierungsregel zugeordnet ist, wird sie von WPF automatisch angewendet, wenn Daten in das gebundene Steuerelement eingegeben werden. Wenn ein Steuerelement ungültige Daten enthält, wird das ungültige Steuerelement von WPF mit einem roten Rahmen angezeigt, wie in der folgenden Abbildung gezeigt.
WPF beschränkt Benutzer nicht so lange auf das ungültige Steuerelement, bis sie gültige Daten eingegeben haben. Das wird als gutes Verhalten für ein Dialogfeld verstanden: Benutzer sollten in einem Dialogfeld frei durch die Steuerelemente navigieren können, unabhängig davon, ob die Daten gültig sind. Dies bedeutet allerdings, dass ein Benutzer ungültige Daten eingeben und auf die Schaltfläche OK klicken kann. Aus diesem Grund muss Ihr Code auch für die Überprüfung aller Steuerelemente in einem Dialogfeld sorgen, wenn auf die Schaltfläche OK geklickt wird. Dies geschieht durch Behandlung des Click-Ereignisses.
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
Von diesem Code werden alle Abhängigkeitsobjekte in einem Fenster aufgelistet. Befinden sich ungültige Objekte darunter, (wie sie von GetHasError zurückgegeben werden), erhält das ungültige Steuerelement den Fokus, die IsValid
-Methode gibt false
zurück, und das Fenster wird als ungültig angesehen.
Sobald ein Dialogfeld gültig ist, kann es sicher geschlossen und zurückgegeben werden. Als Teil des Rückgabevorgangs muss es ein Ergebnis an die aufrufende Funktion zurückgeben.
Festlegen des Ergebnisses eines modalen Dialogfelds
Das Öffnen eines Dialogfelds mit ShowDialog entspricht grundsätzlich dem Aufrufen einer Methode: Der Code, der das Dialogfeld mithilfe von ShowDialog geöffnet hat, wartet, bis ShowDialog zurückkehrt. Wenn ShowDialog zurückkehrt, muss der Code, der es aufgerufen hat, entscheiden, ob die Verarbeitung fortgesetzt oder abgebrochen wird, je nachdem, ob der Benutzer auf die Schaltfläche OK oder auf Abbrechen geklickt hat. Zum Erleichtern dieser Entscheidung muss das Dialogfeld die Auswahl des Benutzers als Boolean-Wert zurückgeben, der von der Methode ShowDialog zurückgegeben wird.
Wenn auf die Schaltfläche OK geklickt wird, sollte ShowDialogtrue
zurückgeben. Dies wird erreicht, indem die DialogResult-Eigenschaft des Dialogfelds festgelegt wird, wenn auf die Schaltfläche OK geklickt wird.
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
Beachten Sie, dass das Festlegen der DialogResult-Eigenschaft zugleich das automatische Schließen des Fensters bewirkt, was den expliziten Aufruf von Close überflüssig macht.
Wenn auf die Schaltfläche Abbrechen geklickt wird, sollte ShowDialogfalse
zurückgeben, wofür ebenfalls das Festlegen der DialogResult-Eigenschaft erforderlich ist.
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
Wenn die Eigenschaft IsCancel einer Schaltfläche auf true
festgelegt ist und der Benutzer entweder auf die Schaltfläche Abbrechen klickt oder die ESC-Taste drückt, wird DialogResult automatisch auf false
festgelegt. Das folgende Markup hat denselben Effekt wie der vorhergehende Code, ohne dass das Click-Ereignis behandelt werden muss.
<Button Name="cancelButton" IsCancel="True">Cancel</Button>
Ein Dialogfeld gibt automatisch false
zurück, wenn ein Benutzer in der Titelleiste auf die Schaltfläche Schließen klickt oder im Systemmenü das Menüelement Schließen auswählt.
Verarbeiten von Daten, die von einem modalen Dialogfeld zurückgegeben werden
Wenn DialogResult von einem Dialogfeld festgelegt wird, kann die Funktion, die es geöffnet hat, das Ergebnis des Dialogfelds abrufen, indem es die Eigenschaft DialogResult in der Rückgabe von ShowDialog untersucht.
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
Wenn das Dialogergebnis true
ist, wird dies von der Funktion als Hinweis verwendet, die vom Benutzer bereitgestellten Daten abzurufen und zu verarbeiten.
Hinweis
Nach der Rückkehr von ShowDialog kann ein Dialogfeld nicht mehr geöffnet werden. Stattdessen müssen Sie eine neue Instanz erstellen.
Wenn das Dialogergebnis false
ist, sollte die Funktion die Verarbeitung entsprechend beenden.
Erstellen eines nicht modalen benutzerdefinierten Dialogfelds
Ein nicht modales Dialogfeld, z. B. das in der folgenden Abbildung dargestellte Dialogfeld „Suchen“, besitzt dasselbe grundlegende Aussehen wie das modale Dialogfeld.
Allerdings ist das Verhalten etwas anders, wie in den folgenden Abschnitten beschrieben wird.
Öffnen eines nicht modalen Dialogfelds
Ein nicht modales Dialogfeld wird durch Aufrufen der Methode Show geöffnet.
<!--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
Im Gegensatz zu ShowDialog kehrt Show sofort zurück. Dementsprechend kann das aufrufende Fenster nicht erkennen, wann das nicht modale Dialogfeld geschlossen wird, und weiß deshalb auch nicht, wann es ein Dialogfeldergebnis überprüfen oder Daten vom Dialogfeld zur weiteren Verarbeitung abrufen soll. Stattdessen muss vom Dialogfeld eine andere Möglichkeit erstellt werden, um Daten an das aufrufende Fenster zur Verarbeitung zurückzugeben.
Verarbeiten von Daten, die von einem nicht modalen Dialogfeld zurückgegeben werden
In diesem Beispiel kann FindDialogBox
ein oder mehrere Suchergebnisse an das Hauptfenster zurückgeben, je nach Suchtext ohne besondere Häufigkeit. Wie ein modales Dialogfeld kann auch ein nicht modales Dialogfeld Ergebnisse mithilfe von Eigenschaften zurückgeben. Das Fenster, das Besitzer des Dialogfelds ist, muss jedoch wissen, wann es diese Eigenschaften überprüfen soll. Diese Funktionalität kann z. B. dadurch aktiviert werden, dass das Dialogfeld ein Ereignis implementiert, das jedes Mal ausgelöst wird, wenn Text gefunden wird. FindDialogBox
implementiert zu diesem Zweck TextFoundEvent
, wobei zuerst ein Delegat erforderlich ist.
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
Mithilfe des TextFoundEventHandler
-Delegaten implementiert FindDialogBox
das 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
Infolgedessen kann Find
das Ereignis auslösen, wenn ein Suchergebnis gefunden wird.
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
Das Besitzerfenster muss anschließend bei diesem Ereignis registriert werden und es behandeln.
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
Schließen eines nicht modalen Dialogfelds
Weil DialogResult nicht festgelegt werden muss, kann ein nicht modales Dialogfeld mithilfe von systemeigenen Mechanismen geschlossen werden. Dazu zählen:
Klicken auf die Schaltfläche Schließen in der Titelleiste.
Drücken von ALT+F4.
Auswählen von Schließen im Systemmenü.
Der Code kann alternativ Close aufrufen, wenn auf die Schaltfläche Schließen geklickt wird.
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
Siehe auch
.NET Desktop feedback