Freigeben über


Übersicht über Dialogfelder

Eigenständige Anwendungen verfügen üblicherweise über ein Hauptfenster, in dem die wichtigen Daten, mit denen die Anwendung arbeitet, angezeigt werden, und das die Funktionen verfügbar macht, um diese Daten mithilfe von user interface (UI)-Mechanismen wie Menüleisten, Symbolleisten und Statusleisten zu verarbeiten. Eine wichtige Anwendung kann auch zusätzliche Fenster anzeigen, um folgende Aufgaben auszuführen:

  • Anzeigen von besonderen Informationen für Benutzer.

  • Erfassen von Informationen von Benutzern.

  • Anzeigen und Erfassen von Informationen.

Diese Typen von Fenstern werden als Dialogfelder bezeichnet. Es gibt zwei Typen: modale und nicht modale.

Ein modales Dialogfeld wird durch eine Funktion angezeigt, wenn die Funktion zum Fortfahren zusätzliche Daten von einem Benutzer benötigt. Da die Funktion zum Sammeln der Daten vom modalen Dialogfeld abhängig ist, verhindert das modale Dialogfeld, so lange es geöffnet ist, auch, dass ein Benutzer andere Fenster in der Anwendung aktiviert. 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 Windows Presentation Foundation (WPF) 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.

Dieses Thema enthält folgende Abschnitte.

  • Meldungsfelder
  • Häufig verwendete Dialogfelder
  • Benutzerdefinierte Dialogfelder
  • Verwandte Abschnitte

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.

Dialogfeld Textverarbeitung

Ein Meldungsfeld wird mithilfe der MessageBox-Klasse erstellt. Mit MessageBox können Sie den Text, den Titel, das Symbol und die Schaltflächen im Meldungsfeld konfigurieren, indem Sie folgenden Code verwenden.

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

Um ein Meldungsfeld anzuzeigen, 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
Dim result As MessageBoxResult = MessageBox.Show(messageBoxText, caption, button, icon)

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

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

Weitere Informationen zum Verwenden von Meldungsfeldern finden Sie unter MessageBox, Beispiel zu MessageBox und Beispiel für ein Dialogfeld.

Obwohl MessageBox bereits ein einfaches Beispiel für die Benutzererfahrung mit Dialogfeldern bietet, liegt der Vorteil der Verwendung von MessageBox darin, dass es der einzige Fenstertyp ist, der von Anwendungen angezeigt werden kann, die in einer teilweise vertrauenswürdigen Sicherheitssandbox (siehe Sicherheit (WPF)), z. B. XAML browser applications (XBAPs), ausgeführt werden.

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 Windows Presentation Foundation (WPF) mehrere Standarddialogfelder zur Verfügung und ermöglicht es Ihnen, eigene Dialogfelder zu erstellen, obwohl die Verwendung beider Typen auf Anwendungen begrenzt ist, die mit voller Vertrauenswürdigkeit ausgeführt werden.

Häufig verwendete Dialogfelder

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.

Windows Presentation Foundation (WPF) 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.

Dialogfeld Öffnen

Der Standarddialogfeld Datei öffnen wird 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
Dim dlg As New Microsoft.Win32.OpenFileDialog()
dlg.FileName = "Document" ' Default file name
dlg.DefaultExt = ".txt" ' Default file extension
dlg.Filter = "Text documents (.txt)|*.txt" ' Filter files by extension

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

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

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

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

Weitere Informationen über das Dialogfeld Datei öffnen finden Sie unter Microsoft.Win32.OpenFileDialog.

HinweisHinweis

Mit OpenFileDialog können Dateinamen von Anwendungen, die mit teilweiser Vertrauenswürdigkeit ausgeführt werden, sicher abgerufen werden (siehe Sicherheit (WPF)).

Dialogfeld "Datei speichern"

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.

Dialogfeld Speichern unter

Der Standarddialogfeld Datei speichern wird 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
Dim dlg As New Microsoft.Win32.SaveFileDialog()
dlg.FileName = "Document" ' Default file name
dlg.DefaultExt = ".text" ' Default file extension
dlg.Filter = "Text documents (.txt)|*.txt" ' Filter files by extension

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

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

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

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

Weitere Informationen über das 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.

Dialogfeld Drucken

Der Standarddialogfeld Drucken wird 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
Dim dlg As New PrintDialog()
dlg.PageRangeSelection = PageRangeSelection.AllPages
dlg.UserPageRangeEnabled = True

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

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

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

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

Weitere Informationen über das Dialogfeld 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. Das Window-Element implementiert jene Verhaltensweisen und infolgedessen verwenden Sie das Window-Element, um benutzerdefinierte modale und nicht modale Dialogfelder zu erstellen.

Erstellen eines modalen benutzerdefinierten Dialogfelds

In diesem Thema wird beschrieben, wie das Window-Element verwendet wird, um eine typische modale Dialogfeldimplementierung zu erstellen. Das Dialogfeld Margins dient als Beispiel (siehe Beispiel für ein Dialogfeld). Das Dialogfeld Margins wird in der folgenden Abbildung angezeigt.

Dialogfeld Ränder

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.

  • Ein Symbol.

  • Schaltflächen zum Minimieren, Maximieren und Wiederherstellen.

  • Ein Systemmenü zum Minimieren, Maximieren, Wiederherstellen und Schließen des Dialogfelds.

  • Eine freie Stelle über und in der Mitte des Fensters, das das Dialogfeld geöffnet hat.

  • Die Größe von Dialogfeldern sollte sich nach Möglichkeit ändern lassen. Um zu verhindern, dass das Dialogfeld zu klein ist, und um für den Benutzer eine sinnvolle Standardgröße bereitzustellen, müssen Sie jeweils die Standard- und Mindestgröße festlegen.

  • Das Drücken der ESC-TASTE sollte als Tastenkombination konfiguriert werden, die bewirkt, dass die Schaltfläche Abbrechen gedrückt wird. Dies wird erreicht, indem die IsCancel-Eigenschaft der Schaltfläche Abbrechen auf true festgelegt wird.

  • Das Drücken der EINGABETASTE sollte als Tastenkombination konfiguriert werden, die bewirkt, dass die Schaltfläche OK gedrückt wird. Dies wird erreicht, indem die IsDefault-Eigenschaft der Schaltfläche OK auf true festgelegt wird.

Im folgenden Code wird diese Konfiguration veranschaulicht.


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

  <Grid>


...


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

  </Grid >

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

Namespace SDKSample


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


...


End Class

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

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


...


    }
}

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.


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

Namespace SDKSample

Public Class MainWindow
    Inherits Window


...


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

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

        ' Open the dialog box modally 
        dlg.ShowDialog()



...


End Sub


...


End Class

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

namespace SDKSample
{
    public partial class MainWindow : Window
    {


...


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

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

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



...


}


...


    }
}

An dieser Stelle werden vom Code Standardinformationen (die aktuellen Ränder) an das Dialogfeld übergeben. Im Beispiel wird auch die Window.Owner-Eigenschaft mit einem Verweis auf das Fenster, das das Dialogfeld anzeigt, festgelegt. 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).

HinweisHinweis

Sie müssen einen Besitzer bereitstellen, um die user interface (UI)-Automatisierung für Dialogfelder zu unterstützen (siehe Übersicht über die Benutzeroberflächenautomatisierung).

Nachdem das Dialogfeld konfiguriert ist, wird es durch Aufrufen der ShowDialog-Methode 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.

Um ein gebundenes Steuerelement in WPF zu überprüfen, müssen Sie eine Validierungsregel definieren und diese der Bindung zuordnen. Eine Validierungsregel ist eine benutzerdefinierte Klasse, die von ValidationRule abgeleitet wird. Im folgenden Beispiel wird die Validierungsregel MarginValidationRule gezeigt, die überprüft, ob ein gebundener Wert ein Double ist und in einem bestimmten Bereich liegt.

Imports System.Globalization
Imports System.Windows.Controls

Namespace SDKSample

Public Class MarginValidationRule
    Inherits ValidationRule

    Private _maxMargin As Double
    Private _minMargin As Double

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

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

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

        Dim margin As Double

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

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

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

    End Function

End Class

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

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

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

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

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

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

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

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

In diesem Code wird die Validierungslogik einer Validierungsregel durch Überschreiben der Validate-Methode 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="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.MarginsDialogBox"
    xmlns:local="clr-namespace:SDKSample"
    Title="Margins"
    Height="190"
    Width="300"
    MinHeight="10"
    MinWidth="300"
    ResizeMode="CanResizeWithGrip"
    ShowInTaskbar="False"
    WindowStartupLocation="CenterOwner" 
    FocusManager.FocusedElement="{Binding ElementName=leftMarginTextBox}">

  <Grid>
    


...


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


...


</Window>

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.

Ungültiger linker Rand

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 müssen alle Steuerelemente in einem Dialogfeld vom Code auch überprüft werden, wenn auf die Schaltfläche OK geklickt wird. Dies geschieht durch Behandlung des Click-Ereignisses.

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

Namespace SDKSample


Public Class MarginsDialogBox
    Inherits Window


...


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


...


    End Sub

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

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

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

        ' All dependency objects are valid
        Return True

    End Function

End Class

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

namespace SDKSample
{
    public partial class MarginsDialogBox : Window
    {


...


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


...


        }

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

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

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

Alle Abhängigkeitsobjekte in einem Fenster werden von diesem Code 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 modalen Dialogergebnisses

Das Öffnen eines Dialogfelds mithilfe von ShowDialog entspricht im Wesentlichen dem Aufruf einer Methode: Der Code, der das Dialogfeld mithilfe von ShowDialog geöffnet hat, wartet, bis ShowDialog zurückgegeben wird. Wenn ShowDialog zurückgegeben wird, muss der Code, der die Methode 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. Um diese Entscheidung zu erleichtern, muss das Dialogfeld die Auswahl des Benutzers als Boolean Wert zurückgeben, der von der ShowDialog-Methode zurückgegeben wird.

Wenn auf die Schaltfläche OK geklickt wurde, sollte ShowDialog true zurückgeben. Dies wird erreicht, indem die DialogResult-Eigenschaft des Dialogfelds festgelegt wird, wenn auf die Schaltfläche OK geklickt wird.

Beachten Sie, dass das Festlegen der DialogResult-Eigenschaft auch bewirkt, dass das Fenster automatisch geschlossen wird, wodurch Close nicht explizit aufgerufen werden muss.

Wenn auf die Schaltfläche Abbrechen geklickt wird, sollte ShowDialog false zurückgeben, wodurch es auch erforderlich wird, die DialogResult-Eigenschaft festzulegen.

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

Namespace SDKSample


Public Class MarginsDialogBox
    Inherits Window


...


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


...


End Class

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

namespace SDKSample
{
    public partial class MarginsDialogBox : Window
    {


...


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


...


    }
}

Wenn die IsCancel-Eigenschaft einer Schaltfläche auf true festgelegt wird und der Benutzer 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 Dialogfeldergebnis abrufen, indem sie die DialogResult-Eigenschaft überprüft, wenn ShowDialog zurückgegeben wird.


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

Namespace SDKSample

Public Class MainWindow
    Inherits Window


...


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


...


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


...


End Class

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

namespace SDKSample
{
    public partial class MainWindow : Window
    {


...


void formatMarginsMenuItem_Click(object sender, RoutedEventArgs e)
{


...


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


...


    }
}

Wenn das Dialogergebnis true ist, wird dies von der Funktion als Hinweis verwendet, um die vom Benutzer bereitgestellten Daten abzurufen und zu verarbeiten.

HinweisHinweis

Nachdem ShowDialog zurückgegeben wurde, kann ein Dialogfeld nicht erneut 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.

Dialogfeld Suchen

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 Show-Methode geöffnet.

<!--Main Window-->

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

Namespace SDKSample

Public Class MainWindow
    Inherits Window


...


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


...


End Class

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

namespace SDKSample
{
    public partial class MainWindow : Window
    {


...


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

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

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


...


    }
}

Im Gegensatz zu ShowDialog wird Show sofort zurückgegeben. 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 TextFoundEvent zu diesem Zweck, wobei zuerst ein Delegat erforderlich ist.

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

Mithilfe des TextFoundEventHandler-Delegaten implementiert FindDialogBox das TextFoundEvent.

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

Namespace SDKSample

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


...


End Class

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

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


...


    }
}

Infolgedessen kann Find das Ereignis auslösen, wenn ein Suchergebnis gefunden wird.

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

Namespace SDKSample

Public Class FindDialogBox
    Inherits Window


...


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


...


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


...


End Sub


...


End Class

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

namespace SDKSample
{
    public partial class FindDialogBox : Window
    {


...


void findNextButton_Click(object sender, RoutedEventArgs e)
{


...


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


...


}


...


    }
}

Das Besitzerfenster muss anschließend bei diesem Ereignis registriert werden und es behandeln.


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

Namespace SDKSample

Public Class MainWindow
    Inherits Window


...


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

End Class

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

namespace SDKSample
{
    public partial class MainWindow : Window
    {


...


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

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

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.

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

Namespace SDKSample

Public Class FindDialogBox
    Inherits Window


...


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

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

namespace SDKSample
{
    public partial class FindDialogBox : Window
    {


...


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

Siehe auch

Konzepte

Übersicht über Popups

Weitere Ressourcen

Beispiel für ein Dialogfeld

Beispiel zum benutzerdefinierten ColorPicker-Steuerelement