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.
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 static
Show, 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.
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.
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.
Caixa de diálogo Imprimir
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.
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.
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 OK
true
.
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.
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 false
e 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
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.
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
.NET Desktop feedback