Freigeben über


Übersicht über Dialogfelder

Eigenständige Anwendungen verfügen in der Regel über ein Hauptfenster, in dem die Hauptdaten angezeigt werden, mit denen die Anwendung arbeitet. Die Funktionalität zum Verarbeiten dieser Daten wird über Benutzeroberflächenmechanismen wie Menüleisten, Symbolleisten und Statusleisten bereitgestellt. Eine nicht triviale Anwendung kann auch zusätzliche Fenster anzeigen, um Folgendes auszuführen:

  • Zeigen Sie benutzern bestimmte Informationen an.

  • 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 vom modalen Dialogfeld zum Sammeln von Daten abhängt, verhindert das modale Dialogfeld auch, dass ein Benutzer andere Fenster in der Anwendung aktiviert, während es 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 Drücken der Schaltfläche OK wird angegeben, dass ein Benutzer Daten eingegeben hat und die Funktion die Verarbeitung mit diesen Daten fortsetzen soll. Durch Drücken der Schaltfläche Abbrechen wird angegeben, dass ein Benutzer die Ausführung der Funktion beenden möchte. Die am häufigsten verwendeten Beispiele für modale Dialogfelder werden angezeigt, um Daten zu öffnen, zu speichern und zu drucken.

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, öffnet ein Hauptfenster häufig ein Dialogfeld, um einen Benutzer zu fragen, nach welchem Wort er sucht. Da das Suchen eines Worts nicht verhindert, dass ein Benutzer das Dokument bearbeitet, muss das Dialogfeld jedoch nicht 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 Arten von Dialogfeldern erstellen, einschließlich Meldungsfeldern, gängigen Dialogfeldern und benutzerdefinierten Dialogfeldern. In diesem Thema wird jeder Typ erläutert, und das Dialogfeldbeispiel stellt entsprechende Beispiele bereit.

Meldungsfelder

Ein Meldungsfeld ist ein Dialogfeld, das verwendet werden kann, um Textinformationen anzuzeigen und Benutzern das Treffen von Entscheidungen mit Schaltflächen zu ermöglichen. Die folgende Abbildung zeigt ein Meldungsfeld, das Textinformationen anzeigt, eine Frage stellt und dem Benutzer drei Schaltflächen zum Beantworten der Frage bereitstellt.

Ein Dialogfeld

Zum Erstellen eines Meldungsfelds verwenden Sie die MessageBox Klasse. mit MessageBox können Sie den Meldungsfeldtext, den Titel, das Symbol und die Schaltflächen mithilfe von Code wie den folgenden konfigurieren.

// 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 staticShow-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 erkennen und verarbeiten muss (welche Schaltfläche gedrückt wurde), kann der Code das Ergebnis des Meldungsfelds prü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 Meldungsfeldern finden Sie unter MessageBox, Meldungsfeld-Beispielund Dialogfeld-Beispiel.

Obwohl MessageBox möglicherweise eine einfache Benutzererfahrung mit Dialogfeldern bietet, liegt der Vorteil der Nutzung von MessageBox darin, dass es sich um den einzigen Fenstertyp handelt, der von Anwendungen angezeigt werden kann, die innerhalb einer Sicherheits-Sandbox mit teilweisem Vertrauen ausgeführt werden (siehe Security), wie z. B. 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.

Allgemeine Dialogfelder

Windows implementiert eine Vielzahl wiederverwendbarer Dialogfelder, die allen Anwendungen gemeinsam sind, einschließlich Dialogfelder zum Öffnen von Dateien, Speichern von Dateien und Drucken. Da diese Dialogfelder vom Betriebssystem implementiert werden, können sie für alle Anwendungen freigegeben werden, die auf dem Betriebssystem ausgeführt werden, wodurch die Konsistenz der Benutzererfahrung verbessert wird. Wenn Benutzer mit der Verwendung eines von einem Betriebssystem bereitgestellten Dialogfelds in einer Anwendung vertraut sind, müssen sie nicht erfahren, wie Sie dieses Dialogfeld in anderen Anwendungen verwenden. Da diese Dialogfelder für alle Anwendungen verfügbar sind und ihnen dabei helfen, eine konsistente Benutzererfahrung zu bieten, werden sie als gängige Dialogfelderbezeichnet.

Windows Presentation Foundation (WPF) kapselt die geöffnete Datei, speichert die Datei und druckt allgemeine Dialogfelder und macht sie als verwaltete Klassen verfügbar, die Sie in eigenständigen Anwendungen verwenden können. Dieses Thema bietet eine kurze Übersicht über jedes einzelne.

Dialogfeld „Datei öffnen“

Das in der folgenden Abbildung gezeigte Dialogfeld "Datei öffnen" wird von der Dateiöffnungsfunktion verwendet, um den Namen einer zu öffnenden Datei abzurufen.

Dialogfeld „Öffnen“ mit dem Speicherort zum Abrufen der Datei

Das allgemeine Dialogfeld für geöffnete Dateien wird als OpenFileDialog Klasse implementiert und befindet sich im Microsoft.Win32 Namespace. Der folgende Code zeigt, wie sie eins erstellen, konfigurieren und anzeigen 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.

Anmerkung

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

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“ mit dem Speicherort zum Speichern der Datei

Das allgemeine Dialogfeld "Datei speichern" wird als SaveFileDialog Klasse implementiert und befindet sich im Microsoft.Win32 Namespace. Der folgende Code zeigt, wie sie eins erstellen, konfigurieren und anzeigen 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.

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.

Screenshot, der ein Dialogfeld zum Drucken zeigt.

Das allgemeine Druckdialogfeld wird als PrintDialog-Klasse implementiert und befindet sich im System.Windows.Controls-Namespace. Der folgende Code zeigt, wie Sie eins erstellen, konfigurieren und anzeigen.

// 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 "Drucken" finden Sie unter System.Windows.Controls.PrintDialog. Ausführliche Erläuterungen zum Drucken in WPF finden Sie unter Druckübersicht.

Benutzerdefinierte Dialogfelder

Allgemeine Dialogfelder sind zwar nützlich und sollten nach Möglichkeit verwendet werden, aber sie unterstützen nicht die Anforderungen domänenspezifischer Dialogfelder. In diesen Fällen müssen Sie eigene Dialogfelder erstellen. Wie wir sehen, ist ein Dialogfeld ein Fenster mit speziellen 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 gezeigt, wie Sie Window verwenden, um eine typische modale Dialogfeldimplementierung zu erstellen, wobei das Dialogfeld Margins als Beispiel dient (siehe Dialogfeldbeispiel). Das Dialogfeld Margins wird in der folgenden Abbildung gezeigt.

Dialogfeld

Konfigurieren eines modalen Dialogfelds

Die Benutzeroberfläche für ein typisches Dialogfeld enthält Folgendes:

  • Die verschiedenen Steuerelemente, die zum Sammeln 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 Position mittig oberhalb des Fensters, das das Dialogfeld geöffnet hat.

  • Die Möglichkeit, die Größe nach Bedarf anzupassen, um zu verhindern, dass das Dialogfeld zu klein ist, und dem Benutzer eine nützliche Standardgröße zu bieten. Dies erfordert, 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.

Der folgende Code veranschaulicht diese Konfiguration.

<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 Benutzeroberfläche für ein Dialogfeld erstreckt sich auch in die Menüleiste des Fensters, in dem das Dialogfeld geöffnet wird. 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 in der Regel als Ergebnis angezeigt, dass 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, erfordert jedoch eine zusätzliche Dialogfeld-spezifische Konfiguration. Der gesamte Prozess zum Instanziieren, Konfigurieren und Öffnen eines Dialogfelds wird im folgenden Code angezeigt.

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 übergibt der Code Standardinformationen (die aktuellen Seitenränder) an das Dialogfeld. Außerdem wird die Eigenschaft Window.Owner auf einen Verweis auf das Fenster festgelegt, in dem das Dialogfeld angezeigt wird. Im Allgemeinen sollten Sie den Besitzer für ein Dialogfeld immer so festlegen, dass fensterzustandsbezogene Verhaltensweisen bereitgestellt werden, die allen Dialogfeldern gemeinsam sind (weitere Informationen finden Sie unter WPF Windows Overview).

Anmerkung

Sie müssen einen Besitzer angeben, um die Automatisierung der 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 von vom Benutzer bereitgestellten Daten

Wenn ein Dialogfeld geöffnet wird und der Benutzer die erforderlichen Daten bereitstellt, ist ein Dialogfeld dafür verantwortlich, dass die bereitgestellten Daten aus den folgenden Gründen gültig sind:

  • Aus Sicherheitsgründen sollten alle Eingaben überprüft werden.

  • Aus domänenspezifischer Sicht verhindert die Datenüberprüfung, dass fehlerhafte Daten vom Code verarbeitet werden, wodurch möglicherweise Ausnahmen ausgelöst werden können.

  • Für eine bessere Benutzererfahrung kann ein Dialogfeld dazu beitragen, Benutzern zu helfen, indem ihnen gezeigt wird, welche der von ihnen eingegebenen Daten ungültig sind.

  • Aus Leistungsperspektive kann die Datenüberprüfung in einer mehrstufigen Anwendung die Anzahl der Roundtrips zwischen dem Client und den Anwendungsebenen verringern, 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. Das folgende Beispiel zeigt eine Gültigkeitsprüfungsregel, MarginValidationRule, die überprüft, ob ein gebundener Wert ein Double ist und sich innerhalb eines angegebenen Bereichs befindet.

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 Gültigkeitsprüfungsregel dem gebundenen Steuerelement zuzuordnen, verwenden Sie das folgende 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>

Sobald die Validierungsregel zugeordnet ist, wird WPF sie automatisch anwenden, wenn Daten in das gebundene Steuerelement eingegeben werden. Wenn ein Steuerelement ungültige Daten enthält, zeigt WPF einen roten Rahmen um das ungültige Steuerelement an, wie in der folgenden Abbildung dargestellt.

Dialogfeld „Ränder“ mit einem roten Rahmen um den ungültigen Wert für den linken Rand

WPF schränkt einen Benutzer nicht auf das ungültige Steuerelement ein, bis er gültige Daten eingegeben hat. Dies ist ein gutes Verhalten für ein Dialogfeld; Ein Benutzer sollte in der Lage sein, die Steuerelemente in einem Dialogfeld frei zu navigieren, unabhängig davon, ob Daten gültig sind. Dies bedeutet jedoch, dass ein Benutzer ungültige Daten eingeben und die Schaltfläche OK drücken 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.

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

Dieser Code listet alle Abhängigkeitsobjekte in einem Fenster auf, und wenn eines ungültig ist (wie von GetHasErrorzurückgegeben), dann erhält das ungültige Steuerelement den Fokus, die IsValid-Methode gibt falsezurück, und das Fenster wird als ungültig betrachtet.

Sobald ein Dialogfeld gültig ist, kann es sicher geschlossen und zurückgegeben werden. Im Rahmen des Rückgabevorgangs muss ein Ergebnis an die aufrufende Funktion zurückgegeben werden.

Festlegen des Ergebnisses eines modalen Dialogfelds

Das Öffnen eines Dialogfelds mit ShowDialog ist im Wesentlichen wie das Aufrufen einer Methode: der Code, der das Dialogfeld mithilfe von ShowDialog geöffnet hat, wartet, bis ShowDialog zurückgegeben wird. Wenn ShowDialog zurückkehrt, muss der aufrufende Code entscheiden, ob die Verarbeitung fortgesetzt oder beendet werden soll, je nachdem, ob der Benutzer die Schaltfläche OK oder die Schaltfläche Abbrechen gedrückt hat. Um diese Entscheidung zu erleichtern, muss das Dialogfeld die Auswahl des Benutzers als Boolean-Wert übermitteln, der von der ShowDialog-Methode ermittelt wird.

Wenn auf die Schaltfläche OK geklickt wird, sollte ShowDialogtruezurückgeben. Dies erreicht man, indem die Eigenschaft DialogResult 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 auch bewirkt, dass das Fenster automatisch geschlossen wird, wodurch die Notwendigkeit verringert wird, Closeexplizit aufzurufen.

Wenn auf die Schaltfläche Abbrechen geklickt wird, sollte ShowDialog false 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 IsCancel-Eigenschaft einer Schaltfläche auf true festgelegt ist und der Benutzer entweder die Schaltfläche Abbrechen oder die ESC-Taste drückt, wird DialogResult automatisch auf falsefestgelegt. Das folgende Markup hat die gleiche Wirkung wie der vorherige 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 die Schaltfläche Schließen in der Titelleiste drückt oder den Menüeintrag Schließen aus dem System Menü auswählt.

Verarbeitung von Daten, die aus 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 Dialogfeldergebnis trueist, verwendet die Funktion diese als Hinweis zum Abrufen und Verarbeiten der vom Benutzer bereitgestellten Daten.

Anmerkung

Nachdem ShowDialog zurückgegeben wurde, kann ein Dialogfeld nicht erneut geöffnet werden. Stattdessen müssen Sie eine neue Instanz erstellen.

Wenn das Dialogfeldergebnis falseist, 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.

Screenshot: Dialogfeld „Suchen“

Das Verhalten unterscheidet sich jedoch geringfügig, wie in den folgenden Abschnitten beschrieben.

Ö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. Folglich kann das aufrufende Fenster nicht erkennen, wann das nicht modale Dialogfeld geschlossen ist, und es ist daher nicht informiert, wann es nach einem Dialogfeldergebnis suchen oder Daten aus dem Dialogfeld zur weiteren Verarbeitung abrufen muss. Stattdessen muss das Dialogfeld eine alternative Möglichkeit zum Zurückgeben von Daten an das aufrufende Fenster zur Verarbeitung erstellen.

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 das Dialogfeld besitzt, muss jedoch wissen, wann diese Eigenschaften überprüft werden sollen. Um dies zu ermöglichen, kann das Dialogfeld ein Ereignis implementieren, das ausgelöst wird, sobald 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