Sdílet prostřednictvím


Přehled dialogových oken

Samostatné aplikace obvykle mají hlavní okno, ve kterém se zobrazují hlavní data, nad kterými aplikace pracuje, a zveřejňuje funkce pro zpracování dat prostřednictvím mechanismů uživatelského rozhraní, jako jsou pruhy nabídek, pruhy nástrojů a stavové pruhy. Aplikace, která není triviální, může také zobrazit další okna, která můžou provádět následující akce:

  • Umožňuje zobrazit konkrétní informace pro uživatele.

  • Shromážděte informace od uživatelů.

  • Zobrazují a shromažďují informace.

Tyto typy oken se označují jako dialogová oknaa existují dva typy: modální a bezmodální.

Funkce zobrazí modální dialogové okno , když funkce potřebuje další data od uživatele, aby pokračovala. Vzhledem k tomu, že funkce závisí na modálním dialogovém okně pro shromažďování dat, modální dialogové okno také zabrání uživateli v aktivaci jiných oken v aplikaci, když zůstane otevřený. Ve většině případů modální dialogové okno umožňuje uživateli signalizovat, když dokončí modální dialogové okno stisknutím tlačítka OK nebo Tlačítko Zrušit. Stisknutím tlačítka OK značí, že uživatel zadal data a chce, aby funkce pokračovala ve zpracování s daty. Když stisknete tlačítko Zrušit, znamená to, že uživatel chce funkci úplně zastavit. Nejběžnější příklady modálních dialogových oken jsou zobrazeny pro otevření, uložení a tisk dat.

Dialogové okno bez režimu na druhé straně nezabrání uživateli v aktivaci jiných oken, když je otevřené. Pokud například uživatel chce najít výskyty určitého slova v dokumentu, hlavní okno často otevře dialogové okno s dotazem uživatele, jaké slovo hledá. Vzhledem k tomu, že hledání slova nezabrání uživateli v úpravě dokumentu, nemusí být dialogové okno modální. Bezmodální dialogové okno obsahuje alespoň tlačítko Zavřít dialogové okno a může poskytnout další tlačítka pro provádění konkrétních funkcí, jako je tlačítko Najít další a najít další slovo, které odpovídá kritériím hledání slov.

Windows Presentation Foundation (WPF) umožňuje vytvořit několik typů dialogových oken, včetně polí zpráv, běžných dialogových oken a vlastních dialogových oken. Toto téma popisuje každou z nich a ukázky dialogového okna poskytují odpovídající příklady.

Oznamovací okna

Pole se zprávou je dialogové okno, které se dá použít k zobrazení textových informací a k tomu, aby uživatelé mohli rozhodovat pomocí tlačítek. Následující obrázek znázorňuje pole se zprávou, které zobrazuje textové informace, položí otázku a poskytne uživateli tři tlačítka pro odpověď na otázku.

dialogové okno Textového procesoru s dotazem, jestli chcete uložit změny dokumentu před zavření aplikace.

Chcete-li vytvořit okno zprávy, použijte třídu MessageBox. MessageBox umožňuje nakonfigurovat text pole se zprávou, název, ikonu a tlačítka pomocí kódu, jako je následující.

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

Pokud chcete zobrazit okno se zprávou, zavoláte metodu staticShow, jak je znázorněno v následujícím kódu.

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

Když kód, který zobrazuje pole se zprávou, musí zjistit a zpracovat rozhodnutí uživatele (které tlačítko bylo stisknuto), může kód zkontrolovat výsledek pole se zprávou, jak je znázorněno v následujícím kódu.

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

Další informace o používání polí zpráv naleznete v tématu MessageBox, MessageBox Samplea Dialog Box Sample.

I když MessageBox může nabídnout jednoduché uživatelské prostředí dialogového okna, výhodou použití MessageBox je jediný typ okna, který můžou zobrazit aplikace, které běží v izolovaném prostoru zabezpečení s částečnou důvěryhodností (viz Zabezpečení), jako jsou aplikace prohlížeče XAML (XBAPs).

Většina dialogových oken zobrazuje a shromažďuje složitější data než výsledek oznamovacího okna, včetně textu, výběru (zaškrtávací políčka), vzájemně se vylučujícího výběru (přepínače) a výběru ze seznamu (seznamová pole, kombo boxy, rozbalovací seznamy). Pro tyto, Windows Presentation Foundation (WPF) poskytuje několik běžných dialogových oken a umožňuje vytvořit vlastní dialogová okna, i když použití některé z nich je omezené na aplikace spuštěné s plnou důvěryhodností.

Běžná dialogová okna

Systém Windows implementuje řadu opakovaně použitelných dialogových oken, která jsou společná pro všechny aplikace, včetně dialogových oken pro otevírání souborů, ukládání souborů a tisku. Vzhledem k tomu, že tato dialogová okna jsou implementována operačním systémem, mohou být sdíleny mezi všemi aplikacemi, které běží v operačním systému, což pomáhá uživatelské prostředí konzistence; pokud uživatelé znají použití dialogového okna poskytovaného operačním systémem v jedné aplikaci, nemusí se naučit používat toto dialogové okno v jiných aplikacích. Vzhledem k tomu, že tato dialogová okna jsou dostupná pro všechny aplikace a pomáhají zajistit konzistentní uživatelské prostředí, označují se jako společná dialogová okna.

Windows Presentation Foundation (WPF) zapouzdřuje otevřený soubor, uloží soubor a vytiskne běžná dialogová okna a zpřístupní je jako spravované třídy, které můžete použít v samostatných aplikacích. Toto téma obsahuje stručný přehled jednotlivých témat.

Dialogové okno Otevřít soubor

Dialogové okno Otevřít soubor, které je znázorněno na následujícím obrázku, se používá při otevírání souborů k načtení názvu souboru, který se má otevřít.

dialogové okno Otevřít zobrazující umístění pro načtení souboru.

Společné otevřené dialogové okno souboru je implementováno jako třída OpenFileDialog a nachází se v Microsoft.Win32 oboru názvů. Následující kód ukazuje, jak vytvořit, nakonfigurovat a zobrazit jeden a jak zpracovat výsledek.

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

Další informace o otevřeném dialogovém okně souboru naleznete v tématu Microsoft.Win32.OpenFileDialog.

Poznámka

OpenFileDialog může být použito pro bezpečné načtení názvů souborů aplikacemi spuštěnými s částečnou úrovní důvěryhodnosti (viz Zabezpečení).

Dialogové okno Uložit soubor

Dialogové okno Uložit soubor, které je znázorněno na následujícím obrázku, používá funkce ukládání souborů k načtení názvu souboru k uložení.

Dialogové okno Uložit jako, které zobrazuje umístění pro uložení souboru.

Běžné dialogové okno pro uložení souboru je implementováno jako třída SaveFileDialog a je umístěno v oboru názvů Microsoft.Win32. Následující kód ukazuje, jak vytvořit, nakonfigurovat a zobrazit jeden a jak zpracovat výsledek.

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

Další informace o dialogovém okně Uložit soubor naleznete v tématu Microsoft.Win32.SaveFileDialog.

Dialogové okno tisk, které je znázorněno na následujícím obrázku, používá funkce tisku k výběru a konfiguraci tiskárny, do které chce uživatel tisknout data.

Snímek obrazovky s dialogovým oknem Tisk

Standardní dialogové okno tisku je implementováno jako třída PrintDialog a nachází se v System.Windows.Controls namespace. Následující kód ukazuje, jak ho vytvořit, nakonfigurovat a zobrazit.

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

Další informace o dialogovém okně tisku naleznete v tématu System.Windows.Controls.PrintDialog. Podrobné informace o tisku ve WPF naleznete v tématu Přehled tisku.

Vlastní dialogová okna

I když jsou běžná dialogová okna užitečná a měla by se používat, pokud je to možné, nepodporují požadavky dialogových oken specifických pro doménu. V těchto případech musíte vytvořit vlastní dialogová okna. Jak uvidíme, dialogové okno je okno se speciálním chováním. Window implementuje toto chování, tudíž použijete Window k vytvoření vlastních modálních a bezmodálních dialogových oken.

Vytvoření modálního vlastního dialogového okna

Toto téma ukazuje, jak pomocí vytvořit typickou modální implementaci dialogového okna pomocí dialogového okna jako příklad (viz ukázkadialogového okna ). Dialogové okno Margins je znázorněno na následujícím obrázku.

dialogové okno Okraje s poli definujícími levý okraj, horní okraj, pravý okraj a dolní okraj.

Konfigurace modálního dialogového okna

Uživatelské rozhraní typického dialogového okna obsahuje následující:

  • Různé ovládací prvky potřebné ke shromáždění požadovaných dat.

  • Tlačítko OK, na které uživatelé kliknou pro zavření dialogového okna, návrat do funkce a pokračování ve zpracování.

  • Tlačítko Zrušit, na které uživatelé kliknou, aby zavřeli dialogové okno a zastavili tuto funkci v dalším zpracování.

  • Tlačítko Zavřít v panelu s titulkem

  • Ikona.

  • tlačítka minimalizovat, maximalizovata obnovit.

  • Nabídka System pro minimalizaci, maximalizaci, obnovení a zavření dialogového okna.

  • Pozice nad a uprostřed okna, která otevřela dialogové okno.

  • Možnost změnit velikost dialogového okna, pokud je to možné, aby nebylo příliš malé, a poskytnout uživateli užitečnou výchozí velikost. To vyžaduje, abyste nastavili výchozí i minimální rozměry.

  • Klávesa ESC jako klávesová zkratka, která způsobí stisknutí tlačítka Zrušit. Provedete to nastavením vlastnosti IsCancel tlačítka Zrušit na true.

  • Klávesa ENTER (nebo RETURN) jako klávesová zkratka, která způsobí stisknutí tlačítka OK. Provedete to nastavením vlastnosti IsDefault tlačítka OKtrue.

Tuto konfiguraci ukazuje následující kód.

<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

Uživatelské prostředí dialogového okna se také rozšíří do řádku nabídek okna, které otevře dialogové okno. Když položka nabídky spustí funkci, která vyžaduje interakci uživatele prostřednictvím dialogového okna, aby funkce mohla pokračovat, položka nabídky pro tuto funkci bude mít tři tečky v záhlaví, jak je zde znázorněno.

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

Když položka nabídky spustí funkci, která zobrazí dialogové okno, které nevyžaduje uživatelskou interakci, například dialogové okno O aplikaci, není nutné použít tři tečky.

Otevření modálního dialogového okna

Dialogové okno se obvykle zobrazuje jako výsledek uživatele, který vybere položku nabídky k provedení funkce specifické pro doménu, například nastavení okrajů dokumentu v textovém procesoru. Zobrazení okna jako dialogového okna je podobné zobrazení normálního okna, i když vyžaduje další konfiguraci specifické pro dialogové okno. Celý proces vytváření instancí, konfigurace a otevření dialogového okna se zobrazí v následujícím kódu.

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

V této části kód předá do dialogového okna výchozí informace (aktuální okraje). Nastaví také vlastnost Window.Owner s odkazem na okno, které zobrazuje dialogové okno. Obecně platí, že byste vždy měli nastavit vlastníka dialogového okna a poskytnout tak chování související se stavem okna, která jsou společná pro všechna dialogová okna (další informace najdete v tématu přehled systému Windows WPF).

Poznámka

Pokud chcete podporovat automatizaci uživatelského rozhraní (UI), musíte zadat vlastníka pro dialogová okna (viz přehledautomatizace uživatelského rozhraní ).

Po nakonfigurování dialogového okna se zobrazí modálně voláním metody ShowDialog.

Ověřování dat zadaných uživatelem

Při otevření dialogového okna a uživatel poskytne požadovaná data, je dialogové okno zodpovědné za zajištění platnosti zadaných dat z následujících důvodů:

  • Z hlediska zabezpečení by se měly ověřit všechny vstupy.

  • Z pohledu specifického pro doménu brání ověření dat chybnému zpracování dat kódem, což může potenciálně vyvolat výjimky.

  • Z pohledu uživatelského prostředí může dialogové okno uživatelům pomoct tím, že uživatelům ukáže, která data zadali, jsou neplatná.

  • Z hlediska výkonu může ověření dat ve vícevrstvé aplikaci snížit počet odezv mezi klientem a aplikačními vrstvami, zejména pokud se aplikace skládá z webových služeb nebo serverových databází.

Pokud chcete ověřit vázaný ovládací prvek ve WPF, musíte definovat ověřovací pravidlo a přidružit ho k vazbě. Ověřovací pravidlo je vlastní třída odvozená od ValidationRule. Následující příklad ukazuje ověřovací pravidlo, MarginValidationRule, který kontroluje, že vázaná hodnota je Double a je v zadaném rozsahu.

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

V tomto kódu je logika ověření ověřovacího pravidla implementována přepsáním metody Validate, která ověřuje data a vrací odpovídající ValidationResult.

Chcete-li přidružit ověřovací pravidlo k vázanému ovládacímu prvku, použijte následující kód.

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

Jakmile je ověřovací pravidlo přidružené, WPF ho automaticky použije při zadání dat do vázaného ovládacího prvku. Pokud ovládací prvek obsahuje neplatná data, WPF zobrazí kolem neplatného ovládacího prvku červené ohraničení, jak je znázorněno na následujícím obrázku.

Dialogové okno Okraje s červeným ohraničením kolem neplatné hodnoty levého okraje.

WPF neomezí uživatele na neplatný ovládací prvek, dokud nezadají platná data. Toto je dobré chování pro dialogové okno; Uživatel by měl mít možnost volně procházet ovládací prvky v dialogovém okně bez ohledu na to, zda jsou data platná. To však znamená, že uživatel může zadat neplatná data a stisknout tlačítko OK. Z tohoto důvodu musí kód také ověřit všechny ovládací prvky v dialogovém okně, když je tlačítko OK stisknuto zpracováním události Click.

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

Tento kód vyčíslí všechny objekty závislostí v okně a pokud některé jsou neplatné (jak je vráceno GetHasError, neplatný ovládací prvek získá fokus, metoda IsValid vrátí falsea okno je považováno za neplatné.

Jakmile je dialogové okno platné, může se bezpečně zavřít a vrátit. V rámci procesu vrácení je potřeba vrátit výsledek funkci, která provádí volání.

Nastavení výsledku modálního dialogového okna

Otevření dialogového okna pomocí ShowDialog je v podstatě podobné volání metody: kód, který otevřel dialogové okno pomocí ShowDialog čeká, dokud ShowDialog nevrátí. Když se ShowDialog vrátí, kód, který ho volal, se musí rozhodnout, jestli se má pokračovat ve zpracování nebo zastavit zpracování, a to na základě toho, jestli uživatel stiskl tlačítko OK nebo tlačítko Zrušit. Aby bylo toto rozhodnutí snazší, musí dialogové okno vrátit volbu uživatele jako hodnotu Boolean vrácenou z metody ShowDialog.

Po kliknutí na tlačítko OK by ShowDialog měla vrátit true. Toho dosáhnete nastavením vlastnosti DialogResult dialogového okna při kliknutí na tlačítko OK.

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

Všimněte si, že nastavení vlastnosti DialogResult také způsobí, že okno se automaticky zavře, což snižuje potřebu explicitně volat Close.

Když se klikne na tlačítko Zrušit, měl by se ShowDialog vrátit na false, což také vyžaduje nastavení vlastnosti DialogResult.

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

Když je vlastnost IsCancel tlačítka nastavená na true a uživatel stiskne tlačítko Zrušit nebo klávesu ESC, DialogResult se automaticky nastaví na false. Následující kód má stejný účinek jako předchozí kód, aniž by bylo nutné zpracovat Click událost.

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

Dialogové okno automaticky vrátí false, když uživatel v záhlaví stiskne tlačítko Zavřít nebo vybere položku nabídky Zavřít z nabídky System.

Zpracování dat vrácených z modálního dialogového okna

Pokud je DialogResult nastavena dialogovým oknem, může funkce, která ji otevřela, získat výsledek dialogového okna kontrolou vlastnosti DialogResult, když se ShowDialog vrátí.

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

Pokud je výsledek dialogového okna true, funkce použije tuto funkci jako pomůcku k načtení a zpracování dat poskytovaných uživatelem.

Poznámka

Po vrácení ShowDialog nelze znovu otevřít dialogové okno. Místo toho je potřeba vytvořit novou instanci.

Pokud je výsledek dialogového okna false, měla by funkce odpovídajícím způsobem ukončit zpracování.

Vytvoření vlastního neblokujícího dialogového okna

Bezmodální dialogové okno, jako je dialogové okno Najít zobrazené na následujícím obrázku, má stejný základní vzhled jako modální dialogové okno.

Snímek obrazovky s dialogovým oknem Najít

Chování se ale mírně liší, jak je popsáno v následujících částech.

Otevření nemodálního dialogového okna

Otevře se neblokující dialogové okno voláním metody Show.

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

Na rozdíl od ShowDialog, Show se vrátí okamžitě. V důsledku toho volající okno nemůže zjistit, kdy je nemodální dialogové okno zavřené, a proto neví, kdy zkontrolovat výsledek dialogového okna nebo získat data z dialogového okna pro další zpracování. Místo toho musí dialogové okno vytvořit alternativní způsob, jak vrátit data do volajícího okna ke zpracování.

Zpracování dat z modeless dialogového okna

V tomto příkladu může FindDialogBox vrátit jeden nebo více výsledků hledání do hlavního okna v závislosti na textu, který hledáte bez jakékoli konkrétní frekvence. Stejně jako u modálního dialogového okna může bezmodální dialogové okno vrátit výsledky pomocí vlastností. Okno, které toto dialogové okno vlastní, ale musí vědět, kdy se mají tyto vlastnosti zkontrolovat. Jedním ze způsobů, jak to umožnit, je nechat dialogové okno provést událost, která se vyvolá vždy, když je nalezen text. FindDialogBox implementuje TextFoundEvent pro tento účel, který nejprve vyžaduje delegáta.

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

Pomocí delegáta TextFoundEventHandlerFindDialogBox implementuje 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

V důsledku toho Find může vyvolat událost, když se najde výsledek hledání.

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

Okno vlastníka se pak musí zaregistrovat a zpracovat tuto událost.

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

Zavření modeless dialogového okna

Vzhledem k tomu, že DialogResult není nutné nastavit, je možné modeless dialogové okno zavřít pomocí systémových mechanismů, včetně následujících:

  • Klikněte na tlačítko Zavřít v záhlaví.

  • Stiskněte kombinaci kláves ALT+F4.

  • V nabídce System zvolte Zavřít.

Případně může kód volat Close, když kliknete na tlačítko Zavřít.

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

Viz také