Partilhar via


Visão geral das caixas de diálogo

Os aplicativos autônomos geralmente têm uma janela principal que exibe os dados principais sobre os quais o aplicativo opera e expõe a funcionalidade para processar esses dados por meio de mecanismos de interface do usuário (UI), como barras de menus, barras de ferramentas e barras de status. Um aplicativo não trivial também pode exibir janelas adicionais para fazer o seguinte:

  • Exibir informações específicas para os usuários.

  • Reúna informações dos usuários.

  • Ambos exibem e coletam informações.

Esses tipos de janelas são conhecidos como caixas de diálogo, e existem dois tipos: modal e não modal.

Quando uma função precisa de dados adicionais de um utilizador para continuar, uma caixa de diálogo modal é exibida. Como a função depende da caixa de diálogo modal para coletar dados, a caixa de diálogo modal também impede que um usuário ative outras janelas no aplicativo enquanto ele permanece aberto. Na maioria das vezes, uma caixa de diálogo modal permite que um utilizador sinalize quando tiver terminado com a caixa de diálogo modal pressionando um OK ou o botão Cancelar. Pressionar o botão OK indica que um usuário inseriu dados e deseja que a função continue processando com esses dados. Pressionar o botão Cancelar indica que um usuário deseja interromper completamente a execução da função. Os exemplos mais comuns de caixas de diálogo modais são mostrados para abrir, salvar e imprimir dados.

Uma caixa de diálogo sem modo , por outro lado, não impede que um utilizador ative outras janelas enquanto está aberta. Por exemplo, se um usuário quiser encontrar ocorrências de uma palavra específica em um documento, uma janela principal geralmente abrirá uma caixa de diálogo para perguntar a um usuário qual palavra ele está procurando. Como encontrar uma palavra não impede que um usuário edite o documento, no entanto, a caixa de diálogo não precisa ser modal. Uma caixa de diálogo não modal fornece pelo menos um botão Fechar para fechar a caixa de diálogo e pode fornecer botões adicionais para executar funções específicas, como um botão Procurar Próximo para localizar a próxima palavra que corresponde aos critérios de pesquisa de uma pesquisa por palavras.

O Windows Presentation Foundation (WPF) permite criar vários tipos de caixas de diálogo, incluindo caixas de mensagem, caixas de diálogo comuns e caixas de diálogo personalizadas. Este tópico discute cada um, e o Exemplo de Caixa de Diálogo fornece exemplos correspondentes.

Caixas de mensagem

Uma caixa de mensagem é uma caixa de diálogo que pode ser usada para exibir informações textuais e permitir que os usuários tomem decisões com botões. A figura a seguir mostra uma caixa de mensagem que exibe informações textuais, faz uma pergunta e fornece ao usuário três botões para responder à pergunta.

Uma caixa de diálogo Processador de texto perguntando se você deseja salvar as alterações no documento antes que o aplicativo seja fechado.

Para criar uma caixa de mensagem, use a classe MessageBox. MessageBox permite configurar o texto, o título, o ícone e os botões da caixa de mensagem, usando um código como o seguinte.

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

Para mostrar uma caixa de mensagem, chame o método staticShow, conforme demonstrado no código a seguir.

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

Quando o código que mostra uma caixa de mensagem precisa detetar e processar a decisão do usuário (qual botão foi pressionado), o código pode inspecionar o resultado da caixa de mensagem, conforme mostrado no código a seguir.

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

Para obter mais informações sobre como usar caixas de mensagem, consulte MessageBox, MessageBox Samplee Dialog Box Sample.

Embora MessageBox possa oferecer uma experiência de utilizador de caixa de diálogo simples, a vantagem de usar MessageBox é que é o único tipo de janela que pode ser exibido por aplicações que executam dentro de uma sandbox de segurança com confiança parcial (consulte Security), como aplicações de navegador XAML (XBAPs).

A maioria das caixas de diálogo exibe e reúne dados mais complexos do que o resultado de uma caixa de mensagem, incluindo texto, seleção (caixas de seleção), seleção mutuamente exclusiva (botões de opção) e seleção de lista (caixas de listagem, caixas de combinação, caixas de listagem suspensas). Para estes, o Windows Presentation Foundation (WPF) fornece várias caixas de diálogo comuns e permite que você crie suas próprias caixas de diálogo, embora o uso de qualquer uma delas seja limitado a aplicativos executados com confiança total.

Caixas de diálogo comuns

O Windows implementa uma variedade de caixas de diálogo reutilizáveis que são comuns a todos os aplicativos, incluindo caixas de diálogo para abrir arquivos, salvar arquivos e imprimir. Como essas caixas de diálogo são implementadas pelo sistema operacional, elas podem ser compartilhadas entre todos os aplicativos executados no sistema operacional, o que ajuda a consistência da experiência do usuário; Quando os usuários estão familiarizados com o uso de uma caixa de diálogo fornecida pelo sistema operacional em um aplicativo, eles não precisam aprender a usar essa caixa de diálogo em outros aplicativos. Como essas caixas de diálogo estão disponíveis para todos os aplicativos e ajudam a fornecer uma experiência de usuário consistente, elas são conhecidas como caixas de diálogo comuns.

Windows Presentation Foundation (WPF) encapsula o arquivo aberto, salvar arquivo e imprimir caixas de diálogo comuns e expõe-os como classes gerenciadas para você usar em aplicativos autônomos. Este tópico fornece uma breve visão geral de cada um deles.

Caixa de diálogo Abrir ficheiro

A caixa de diálogo abrir arquivo, mostrada na figura a seguir, é usada pela funcionalidade de abertura de arquivo para recuperar o nome de um arquivo a ser aberto.

Uma caixa de diálogo Abrir mostrando o local para recuperar o arquivo.

A caixa de diálogo de arquivo aberto comum é implementada como a classe OpenFileDialog e está localizada no namespace Microsoft.Win32. O código a seguir mostra como criar, configurar e mostrar um, e como processar o resultado.

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

Para obter mais informações sobre a caixa de diálogo abrir arquivo, consulte Microsoft.Win32.OpenFileDialog.

Observação

OpenFileDialog pode ser usado para recuperar nomes de arquivos com segurança por aplicativos executados com confiança parcial (consulte Security).

Caixa de diálogo Salvar arquivo

A caixa de diálogo Salvar arquivo, mostrada na figura a seguir, é usada pela funcionalidade de salvamento de arquivos para recuperar o nome de um arquivo a ser salvo.

Uma caixa de diálogo Salvar como mostrando o local para salvar o arquivo.

A caixa de diálogo comum de salvar arquivo é implementada como a classe SaveFileDialog e está localizada no namespace Microsoft.Win32. O código a seguir mostra como criar, configurar e mostrar um, e como processar o resultado.

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

Para obter mais informações sobre a caixa de diálogo Salvar arquivo, consulte Microsoft.Win32.SaveFileDialog.

A caixa de diálogo de impressão, mostrada na figura a seguir, é usada pela funcionalidade de impressão para escolher e configurar a impressora na qual um usuário gostaria de imprimir dados.

Captura de ecrã que mostra uma caixa de diálogo Imprimir.

A caixa de diálogo de impressão comum é implementada como a classe PrintDialog e está localizada no namespace System.Windows.Controls. O código a seguir mostra como criar, configurar e mostrar um.

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

Para obter mais informações sobre a caixa de diálogo de impressão, consulte System.Windows.Controls.PrintDialog. Para obter uma discussão detalhada sobre a impressão no WPF, consulte Visão geral da impressão.

Caixas de diálogo personalizadas

Embora as caixas de diálogo comuns sejam úteis e devam ser usadas quando possível, elas não suportam os requisitos das caixas de diálogo específicas do domínio. Nesses casos, você precisa criar suas próprias caixas de diálogo. Como veremos, uma caixa de diálogo é uma janela com comportamentos especiais. Window implementa esses comportamentos e, consequentemente, utiliza Window para criar caixas de diálogo modais e não modais personalizadas.

Criando uma caixa de diálogo modal personalizada

Este tópico mostra como usar o Window para criar uma implementação típica de caixa de diálogo modal, usando a caixa de diálogo Margins como exemplo (consulte Exemplo de Caixa de Diálogo ). A caixa de diálogo Margins é mostrada na figura a seguir.

Uma caixa de diálogo Margens com campos para definir a margem esquerda, a margem superior, a margem direita e a margem inferior.

Configurando uma caixa de diálogo modal

A interface do usuário para uma caixa de diálogo típica inclui o seguinte:

  • Os vários controles que são necessários para reunir os dados desejados.

  • Um botão OK que os usuários clicam para fechar a caixa de diálogo, retornar à função e continuar o processamento.

  • Um botão Cancelar no qual os utilizadores clicam para fechar a caixa de diálogo e interromper o processamento da função.

  • Um botão Fechar na barra de título.

  • Um ícone.

  • Botões Minimizar, Maximizare Restaurar.

  • Um System menu para minimizar, maximizar, restaurar e fechar a caixa de diálogo.

  • Uma posição acima e ao centro da janela que abriu a caixa de diálogo.

  • A capacidade de ser redimensionada sempre que possível para evitar que a caixa de diálogo seja muito pequena e para fornecer ao usuário um tamanho padrão útil. Isso requer que você defina as dimensões padrão e mínima.

  • A tecla ESC como um atalho de teclado que faz com que o botão Cancelar seja pressionado. Para fazer isso, defina a propriedade IsCancel do botão Cancelar para true.

  • A tecla ENTER (ou RETURN) como um atalho de teclado que faz com que o botão OK seja pressionado. Para fazer isso, defina a propriedade IsDefault do botão OKtrue.

O código a seguir demonstra essa configuração.

<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

A experiência do usuário para uma caixa de diálogo também se estende para a barra de menus da janela que abre a caixa de diálogo. Quando um item de menu executa uma função que requer a interação do utilizador através de uma caixa de diálogo para que a função possa continuar, o item de menu para a função terá reticências no seu cabeçalho, como mostrado aqui.

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

Quando um item de menu executa uma função que exibe uma caixa de diálogo que não requer interação do usuário, como uma caixa de diálogo Sobre, uma reticência não é necessária.

Abrir uma caixa de diálogo modal

Uma caixa de diálogo geralmente é mostrada como resultado de um usuário selecionar um item de menu para executar uma função específica do domínio, como definir as margens de um documento em um processador de texto. Mostrar uma janela como uma caixa de diálogo é semelhante a mostrar uma janela normal, embora exija configuração adicional específica da caixa de diálogo. Todo o processo de instanciação, configuração e abertura de uma caixa de diálogo é mostrado no código a seguir.

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

Aqui, o código passa informações padrão (as margens atuais) para a caixa de diálogo. Ele também define a propriedade Window.Owner com uma referência à janela que está mostrando a caixa de diálogo. Em geral, você sempre deve definir o proprietário de uma caixa de diálogo para fornecer comportamentos relacionados ao estado da janela que são comuns a todas as caixas de diálogo (consulte WPF Windows Overview para obter mais informações).

Observação

Você deve fornecer um proprietário para oferecer suporte à automação da interface do usuário (UI) para caixas de diálogo (consulte Visão geral da automação da interface do usuário ).

Depois que a caixa de diálogo é configurada, ela é mostrada modalmente chamando o método ShowDialog.

Validação de dados fornecidos pelo usuário

Quando uma caixa de diálogo é aberta e o usuário fornece os dados necessários, uma caixa de diálogo é responsável por garantir que os dados fornecidos sejam válidos pelos seguintes motivos:

  • Do ponto de vista da segurança, todas as entradas devem ser validadas.

  • De uma perspetiva específica do domínio, a validação de dados impede que dados errados sejam processados pelo código, o que poderia gerar exceções.

  • Do ponto de vista da experiência do usuário, uma caixa de diálogo pode ajudar os usuários mostrando quais dados inseridos são inválidos.

  • De uma perspetiva de desempenho, a validação de dados em um aplicativo de várias camadas pode reduzir o número de viagens de ida e volta entre o cliente e as camadas de aplicativo, particularmente quando o aplicativo é composto de serviços Web ou bancos de dados baseados em servidor.

Para validar um controle vinculado no WPF, é necessário definir uma regra de validação e associá-la à ligação. Uma regra de validação é uma classe personalizada que deriva de ValidationRule. O exemplo a seguir mostra uma regra de validação, MarginValidationRule, que verifica se um valor acoplado é um Double e está dentro de um intervalo especificado.

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

Neste código, a lógica de validação de uma regra de validação é implementada substituindo o método Validate, que valida os dados e retorna um ValidationResultapropriado.

Para associar a regra de validação ao controlo vinculado, use o código de marcação seguinte.

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

Uma vez que a regra de validação é associada, o WPF a aplicará automaticamente quando os dados forem inseridos no controle vinculado. Quando um controle contém dados inválidos, o WPF exibirá uma borda vermelha ao redor do controle inválido, conforme mostrado na figura a seguir.

Uma caixa de diálogo Margens com uma borda vermelha ao redor do valor de margem esquerda inválido.

WPF não restringe um usuário ao controle inválido até que eles tenham inserido dados válidos. Este é um bom comportamento para uma caixa de diálogo; Um usuário deve ser capaz de navegar livremente pelos controles em uma caixa de diálogo, independentemente de os dados serem válidos ou não. No entanto, isso significa que um usuário pode inserir dados inválidos e pressionar o botão OK. Por esse motivo, seu código também precisa validar todos os controles em uma caixa de diálogo quando o botão OK é pressionado manipulando o evento 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

Esse código enumera todos os objetos de dependência em uma janela e, se algum for inválido (conforme retornado por GetHasError, o controle inválido obtém o foco, o método IsValid retorna falsee a janela é considerada inválida.

Quando uma caixa de diálogo é válida, ela pode ser fechada e retornada com segurança. Como parte do processo de retorno, ele precisa retornar um resultado para a função de chamada.

Definindo o resultado da caixa de diálogo modal

Abrir uma caixa de diálogo usando ShowDialog é fundamentalmente como chamar um método: o código que abriu a caixa de diálogo usando ShowDialog espera até que ShowDialog retorne. Quando ShowDialog retorna, o código que o chamou precisa decidir se continua o processamento ou interrompe o processamento, com base no fato de o usuário pressionar o botão OK ou o botão Cancelar. Para facilitar essa decisão, a caixa de diálogo precisa retornar a escolha do usuário como um valor de Boolean que é retornado do método ShowDialog.

Quando o botão OK é clicado, ShowDialog deve retornar true. Isso é conseguido definindo a propriedade DialogResult da caixa de diálogo quando o botão OK é clicado.

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

Observe que definir a propriedade DialogResult também faz com que a janela feche automaticamente, o que alivia a necessidade de chamar explicitamente Close.

Quando o botão Cancelar é clicado, ShowDialog deve retornar false, o que também requer a configuração da propriedade 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

Quando a propriedade IsCancel de um botão é definida como true e o usuário pressiona o botão Cancelar ou a tecla ESC, DialogResult é automaticamente definida como false. A marcação a seguir tem o mesmo efeito que o código anterior, sem a necessidade de manipular o evento Click.

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

Uma caixa de diálogo retorna automaticamente quando um usuário pressiona o botão Fechar na barra de título ou escolhe o item de menu Fechar no menu Sistema .

Processando dados retornados de uma caixa de diálogo modal

Quando DialogResult é definido por uma caixa de diálogo, a função que a abriu pode obter o resultado da caixa de diálogo inspecionando a propriedade DialogResult quando ShowDialog retorna.

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

Se o resultado da caixa de diálogo for true, a função usa isso como uma pista para recuperar e processar os dados fornecidos pelo usuário.

Observação

Depois de ShowDialog ter retornado, uma caixa de diálogo não pode ser reaberta. Em vez disso, você precisa criar uma nova instância.

Se o resultado da caixa de diálogo for false, a função deve terminar o processamento adequadamente.

Criando uma caixa de diálogo personalizada sem janela restrita

Uma caixa de diálogo não modal, como a caixa de diálogo Localizar mostrada na figura a seguir, tem a mesma aparência fundamental que a caixa de diálogo modal.

Captura de tela que mostra uma caixa de diálogo Localizar.

No entanto, o comportamento é ligeiramente diferente, conforme descrito nas seções a seguir.

Abrir uma caixa de diálogo não modal

Uma caixa de diálogo não modal é aberta chamando o método 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

Ao contrário ShowDialog, Show retorna imediatamente. Consequentemente, a janela de chamada não consegue determinar quando a caixa de diálogo não modal está fechada e, portanto, não sabe quando verificar o resultado da caixa de diálogo ou obter dados dela para processamento posterior. Em vez disso, a caixa de diálogo precisa criar uma maneira alternativa de retornar dados para a janela de chamada para processamento.

Processando dados retornados por uma caixa de diálogo não modal

Neste exemplo, o FindDialogBox pode retornar um ou mais resultados de localização para a janela principal, dependendo do texto que está sendo pesquisado sem qualquer frequência específica. Como em uma caixa de diálogo modal, uma caixa de diálogo não modal pode retornar resultados usando propriedades. No entanto, a janela proprietária da caixa de diálogo precisa saber quando verificar essas propriedades. Uma maneira de habilitar isso é que a caixa de diálogo implemente um evento que é gerado sempre que o texto é encontrado. FindDialogBox implementa o TextFoundEvent para este propósito, que primeiro requer um delegado.

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

Usando o TextFoundEventHandler delegado, FindDialogBox implementa o 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

Consequentemente, Find pode gerar o evento quando um resultado de pesquisa é encontrado.

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

A janela do proprietário, então, precisa se registrar e lidar com esse evento.

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

Fechar uma caixa de diálogo não modal

Como DialogResult não precisa ser definido, uma caixa de diálogo sem modalidade pode ser fechada usando mecanismos fornecidos pelo sistema, incluindo os seguintes:

  • Clique no botão Fechar na barra de título.

  • Pressionando ALT+F4.

  • Escolher Fechar do menu Sistema.

Como alternativa, seu código pode chamar Close quando o botão Fechar for clicado.

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

Ver também

  • Visão geral do Popup
  • Exemplo de caixa de diálogo