Información general sobre cuadros de diálogo
Actualización: noviembre 2007
Las aplicaciones independientes tienen normalmente una ventana principal, que tanto muestra los datos principales sobre los que funciona la aplicación como expone la funcionalidad de procesamiento de datos a través de mecanismos de interfaz de usuario (UI) tales como barras de menús, barras de herramientas y barras de estado. Una aplicación no trivial también puede mostrar ventanas adicionales para hacer lo siguiente:
Mostrar información específica a los usuarios
Recopilar información de los usuarios.
Tanto mostrar como recopilar información.
Estos tipos de ventanas se conocen como cuadros de diálogo y hay dos tipos: modales y no modales.
Los cuadros de diálogo modales los muestras las funciones cuando necesitan datos adicionales de los usuarios para continuar. Dado que la función depende del cuadro de diálogo modal para recopilar los datos, el cuadro de diálogo modal también impide que un usuario active otras ventanas de la aplicación mientras permanece abierto. En la mayoría de los casos, los cuadros de diálogo modales permiten a los usuarios señalar que han terminado con el cuadro de diálogo modal presionando un botón Aceptar o Cancelar. Al presionar el botón Aceptar se indica que el usuario ha introducido los datos y desea que la función continúe su proceso con esos datos. Presionar el botón Cancelar indica que el usuario desea detener la ejecución de la función. Los ejemplos más comunes de cuadros de diálogo modales se muestran para abrir, guardar e imprimir datos.
Un cuadro de diálogo no modal, por otra parte, no impide que el usuario active otras ventanas mientras está abierto. Por ejemplo, si un usuario desea buscar apariciones de una palabra determinada en un documento, una ventana principal abrirá habitualmente un cuadro de diálogo para preguntar al usuario qué palabra está buscando. Dado que la búsqueda de una palabra no impide que un usuario edite el documento, no obstante, no es necesario que el cuadro de diálogo sea modal. Un cuadro de diálogo no modal proporciona al menos un botón Cerrar para cerrar el cuadro de diálogo y puede proporcionar botones adicionales para ejecutar funciones concretas, como un botón Buscar siguiente para buscar la palabra siguiente que coincida con los criterios de una búsqueda de palabra.
Windows Presentation Foundation (WPF) permite crear varios tipos de cuadros de diálogo, incluidos cuadros de mensaje, cuadros de diálogo comunes y cuadros de diálogo personalizados. Este tema explica cada uno de ellos y Ejemplo Dialog Box proporciona ejemplos relacionados.
Este tema contiene las secciones siguientes.
- Cuadros de mensaje
- Cuadros de diálogo comunes
- Cuadros de diálogo personalizados
- Temas relacionados
Cuadros de mensaje
Un cuadro de mensaje es un cuadro de diálogo que se puede utilizar para mostrar información textual y permitirles que los usuarios tomen decisiones con botones. La figura siguiente muestra un cuadro de mensaje que muestra información textual, hace una pregunta y proporciona al usuario tres botones para responder a la pregunta.
Para crear un cuadro de mensaje, utilice la clase MessageBox. MessageBox permite configurar el texto, el título, el icono y los botones del cuadro de mensaje, utilizando código como el siguiente.
Para mostrar un cuadro de mensaje, llame al método static Show, como se muestra en el código siguiente.
Cuando el código que muestra un cuadro de mensaje necesite detectar y procesar la decisión del usuario (qué botón se presionó), el código puede inspeccionar el resultado del cuadro de mensaje, como se muestra en el código siguiente.
Para obtener más información sobre cómo los cuadros de diálogo, vea MessageBox, Ejemplo MessageBox y Ejemplo Dialog Box.
Aunque MessageBox puede proporcionar una experiencia simple de usuario de cuadro de diálogo, la ventaja de utilizar MessageBox es que se trata del único tipo de ventana que pueden mostrar las aplicaciones que se ejecutan dentro de un recinto de seguridad confiable parcial (vea Seguridad de Windows Presentation Foundation), tal como Aplicaciones del explorador XAML (XBAPs).
La mayoría de los cuadros de diálogo muestran y recopilan datos más complejos que el resultado de un cuadro de mensaje, incluidos texto, selecciones (casillas), selecciones mutuamente excluyentes (botones de opción) y selecciones de lista (cuadros de lista, cuadros combinados, cuadros de lista desplegables). Para éstos, Windows Presentation Foundation (WPF) proporciona varios cuadros de diálogo comunes y permite crear cuadros de diálogo propios, aunque el uso de cualquiera de ellos se limita a aplicaciones que se ejecuten con plena confianza.
Cuadros de diálogo comunes
Windows implementa diversos cuadros de diálogo reutilizables que son comunes para todas las aplicaciones, incluidos cuadros de diálogo para abrir archivos, guardar archivos e imprimir. Puesto que es el sistema operativo el que implementa estos cuadros de diálogo, se pueden compartir entre todas las aplicaciones que se ejecutan en el sistema operativo, los que contribuye a la coherencia de la experiencia del usuario; cuando los usuarios están familiarizados con el uso de un cuadro de diálogo proporcionado por el sistema operativo en una aplicación, no necesitan obtener información sobre cómo utilizar ese cuadro de diálogo en otras aplicaciones. Dado que estos cuadros de diálogo están disponibles para todas las aplicaciones y que ayudan a proporcionar una experiencia de usuario coherente, se conocen como cuadros de diálogo comunes.
Windows Presentation Foundation (WPF) encapsula el archivo abierto, excepto el archivo, e imprime los cuadros de diálogo comunes y los expone como clases administradas para que los utilice en aplicaciones independientes. En este tema se proporciona una breve información general sobre:
Abrir archivo (Diálogo)
La funcionalidad de apertura de archivos utiliza el cuadro de diálogo de apertura de archivos, que se muestra en la figura siguiente, para recuperar el nombre de un archivo a abrir.
El cuadro de diálogo común de apertura de archivos se implementa como la clase OpenFileDialog y se encuentra en el espacio de nombres Microsoft.Win32. El código siguiente muestra cómo crear, configurar y mostrar uno, y cómo procesar el resultado.
Para obtener más información sobre el cuadro de diálogo de apertura de archivos, vea Microsoft.Win32.OpenFileDialog.
Nota
OpenFileDialog se puede utilizar para recuperar sin ningún riesgo los nombres de archivo por aplicaciones que se ejecutan con confianza parcial (vea Seguridad de Windows Presentation Foundation). Vea Ejemplo Safe File Upload from an XBAP para ver una demostración.
Guardar archivo (Cuadro de diálogo)
La funcionalidad de guardado de archivos utiliza el cuadro de diálogo de guardado de archivos, que se muestra en la figura siguiente, para recuperar el nombre de un archivo a guardar.
El cuadro de diálogo común de guardado de archivos se implementa como la clase SaveFileDialog y se encuentra en el espacio de nombres Microsoft.Win32. El código siguiente muestra cómo crear, configurar y mostrar uno, y cómo procesar el resultado.
Para obtener más información sobre el cuadro de diálogo de guardado de archivos, vea Microsoft.Win32.SaveFileDialog.
Imprimir (Cuadro de diálogo)
La funcionalidad de impresión de archivos utiliza el cuadro de diálogo de impresión de archivos, que se muestra en la figura siguiente, para elegir y configurar la impresora en la que el usuario desea imprimir datos.
El cuadro de diálogo común de impresión de archivos se implementa como la clase PrintDialog y se encuentra en el espacio de nombres System.Windows.Controls. El código siguiente muestra cómo crear, configurar y mostrar uno.
Para obtener más información sobre el cuadro de diálogo de impresión de archivos, vea System.Windows.Controls.PrintDialog. Para ver una explicación detallada de la impresión en WPF, vea Información general sobre impresión.
Cuadros de diálogo personalizados
Aunque los cuadros de diálogo comunes son útiles, y se deben utilizar cuando sea posible, no satisfacen las necesidades de los cuadros de diálogo específicos de dominio. En estos casos, es necesario crear cuadros de diálogo propios. Cuando veremos, un cuadro de diálogo es una ventana con comportamientos especiales. Window implementa esos comportamientos y, por consiguiente, utiliza Window para crear cuadros de diálogo modales y no modales personalizados.
Crear un cuadro de diálogo personalizado modal
En este tema se muestra cómo utilizar Window para crear una implementación de un cuadro de diálogo modal típico, utilizando el cuadro de diálogo Margins como ejemplo (vea Ejemplo Dialog Box). El cuadro de diálogo Margins se muestra en la figura siguiente.
Configurar un cuadro de diálogo modal
La interfaz de usuario de un cuadro de diálogo típico incluye lo siguiente:
Los diversos controles necesarios para recopilar los datos deseados.
Mostrar un botón Aceptar en el que los usuarios hacen clic para cerrar el cuadro de diálogo, volver a la función y continuar el proceso.
Mostrar un botón Cancelar en el que los usuarios hagan clic para cerrar el cuadro de diálogo y hacer que la función detenga el proceso.
Mostrar un botón Cerrar en la barra de título.
Mostrar un icono.
Mostrar botones Minimizar, Maximizary Restaurar.
Mostrar un menú Sistema para minimizar, maximizar, restaurar y cerrar el cuadro de diálogo.
Apertura encima y en el centro de la ventana que abrió el cuadro de diálogo.
Los cuadros de diálogo deben ser de tamaño variable cuando sea posible de modo que, para evitar que resulten ser demasiado pequeños y para proporcionar al usuario un tamaño predeterminado útil, deberá establecer tanto unas dimensiones predeterminadas como unas dimensiones mínimas.
Es recomendable configurar la acción de presionar la tecla ESC como un método abreviado de teclado que haga que se presione el botón Cancelar. Esto se logra estableciendo la propiedad IsCancel del botón Cancelar en true.
Es recomendable configurar la acción de presionar la tecla Entrar (o Retorno) como un método abreviado de teclado que provoca que se presione el botón Aceptar. Esto se logra estableciendo la propiedad IsDefault del botón Aceptar en true.
El código siguiente muestra esta configuración.
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.MarginsDialogBox"
xmlns:local="clr-namespace:SDKSample"
Title="Margins"
Height="190"
Width="300"
MinHeight="10"
MinWidth="300"
ResizeMode="CanResizeWithGrip"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner"
FocusManager.FocusedElement="{Binding ElementName=leftMarginTextBox}">
<Grid>
...
<!-- Accept or Cancel -->
<StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="4">
<Button Name="okButton" Click="okButton_Click" IsDefault="True">OK</Button>
<Button Name="cancelButton" IsCancel="True">Cancel</Button>
</StackPanel>
</Grid >
</Window>
Imports System.Windows ' Window, RoutedEventArgs, IInputElement, DependencyObject
Imports System.Windows.Controls ' Validation
Imports System.Windows.Input ' Keyboard
Namespace SDKSample
Public Class MarginsDialogBox
Inherits Window
Public Sub New()
Me.InitializeComponent()
End Sub
...
End Class
End Namespace
using System.Windows; // Window, RoutedEventArgs, IInputElement, DependencyObject
using System.Windows.Controls; // Validation
using System.Windows.Input; // Keyboard
namespace SDKSample
{
public partial class MarginsDialogBox : Window
{
public MarginsDialogBox()
{
InitializeComponent();
}
...
}
}
La experiencia del usuario en un cuadro de diálogo se extiende también a la barra de menús de la ventana que abre el cuadro de diálogo. Cuando un elemento de menú ejecuta una función que requiere interacción con el usuario a través de un cuadro de diálogo antes de que la función pueda continuar, el elemento de menú para la función tendrá puntos suspensivos en su encabezado, como se muestra aquí.
<!--Main Window-->
...
<MenuItem Name="formatMarginsMenuItem" Header="_Margins..." Click="formatMarginsMenuItem_Click" />
Cuando un elemento de menú ejecute una función que muestre un cuadro de diálogo que no requiera interacción con el usuario, como un cuadro de diálogo Acerca de, los puntos suspensivos no son necesarios.
Abrir un cuadro de diálogo modal
Un cuadro de diálogo se muestra normalmente como resultado de la selección de un elemento de menú, por parte de un usuario, para realizar una función específica del dominio, tal como establecer los márgenes de un documento en un procesador de textos. Mostrar una ventana como un cuadro de diálogo es similar a mostrar una ventana normal, aunque requiere la configuración adicional específica del cuadro de diálogo. El proceso completo de crear instancias, configurar y abrir un cuadro de diálogo se muestra en el código siguiente.
Imports System ' EventArgs
Imports System.ComponentModel ' CancelEventArgs
Imports System.Windows ' Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls ' TextChangedEventArgs
Imports Microsoft.Win32 ' OpenFileDialog
Namespace SDKSample
Public Class MainWindow
Inherits Window
...
Private Sub formatMarginsMenuItem_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Instantiate the dialog box
Dim dlg As New MarginsDialogBox
' Configure the dialog box
dlg.Owner = Me
dlg.DocumentMargin = Me.documentTextBox.Margin
' Open the dialog box modally
dlg.ShowDialog()
...
End Sub
...
End Class
End Namespace
using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextChangedEventArgs
using Microsoft.Win32; // OpenFileDialog
namespace SDKSample
{
public partial class MainWindow : Window
{
...
void formatMarginsMenuItem_Click(object sender, RoutedEventArgs e)
{
// Instantiate the dialog box
MarginsDialogBox dlg = new MarginsDialogBox();
// Configure the dialog box
dlg.Owner = this;
dlg.DocumentMargin = this.documentTextBox.Margin;
// Open the dialog box modally
dlg.ShowDialog();
...
}
...
}
}
Aquí, el código está pasando información predeterminada (los márgenes actuales) al cuadro de diálogo. También está estableciendo la propiedad Window.Owner con una referencia a la ventana que está mostrando el cuadro de diálogo. En general, siempre se debe establecer el propietario de un cuadro de diálogo para ofrecer comportamientos relacionados con el estado de la ventana que son comunes a todos los cuadros de diálogo (vea Información general sobre ventanas de WPF para obtener más información).
Nota
Para que sea posible la automatización interfaz de usuario (UI) para cuadros de diálogo (vea Información general sobre UI Automation) debe proporcionar un propietario.
Una vez configurado el cuadro de diálogo, se mostrará modalmente llamando al método ShowDialog.
Validar datos proporcionados por el usuario
Cuando se abre un cuadro de diálogo y el usuario proporciona los datos necesarios, el cuadro de diálogo es responsable de asegurarse que los datos proporcionados sean válidos por las razones siguientes:
Desde la perspectiva de la seguridad, todas las entradas se deben validar.
Desde la perspectiva específica del dominio, la validación de datos impide que el código procese datos erróneos, lo que podría iniciar excepciones.
Desde la perspectiva de un usuario, un cuadro de diálogo puede ayudar a los usuarios mostrándoles qué datos de los introducidos no son válidos.
Desde la perspectiva del rendimiento, la validación de datos en una aplicación de varios niveles puede reducir el número de viajes de ida y vuelta entre los niveles de cliente y de aplicación, en particular cuando la aplicación se compone de servicios web o bases de datos basadas en servidor.
Para validar un control enlazado en WPF, debe definir una regla de validación y asociarla al enlace. Una regla de validación es una clase personalizada derivada de ValidationRule. El ejemplo siguiente muestra una regla de validación, MarginValidationRule, que comprueba que un valor enlazado es Double y está dentro de un intervalo especificado.
Imports System.Globalization
Imports System.Windows.Controls
Namespace SDKSample
Public Class MarginValidationRule
Inherits ValidationRule
Private _maxMargin As Double
Private _minMargin As Double
Public Property MaxMargin() As Double
Get
Return Me._maxMargin
End Get
Set(ByVal value As Double)
Me._maxMargin = value
End Set
End Property
Public Property MinMargin() As Double
Get
Return Me._minMargin
End Get
Set(ByVal value As Double)
Me._minMargin = value
End Set
End Property
Public Overrides Function Validate(ByVal value As Object, ByVal cultureInfo As CultureInfo) As ValidationResult
Dim margin As Double
' Is a number?
If Not Double.TryParse(CStr(value), margin) Then
Return New ValidationResult(False, "Not a number.")
End If
' Is in range?
If ((margin < Me.MinMargin) OrElse (margin > Me.MaxMargin)) Then
Dim msg As String = String.Format("Margin must be between {0} and {1}.", Me.MinMargin, Me.MaxMargin)
Return New ValidationResult(False, msg)
End If
' Number is valid
Return New ValidationResult(True, Nothing)
End Function
End Class
End Namespace
using System.Globalization;
using System.Windows.Controls;
namespace SDKSample
{
public class MarginValidationRule : ValidationRule
{
double minMargin;
double maxMargin;
public double MinMargin
{
get { return this.minMargin; }
set { this.minMargin = value; }
}
public double MaxMargin
{
get { return this.maxMargin; }
set { this.maxMargin = value; }
}
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
double margin;
// Is a number?
if (!double.TryParse((string)value, out margin))
{
return new ValidationResult(false, "Not a number.");
}
// Is in range?
if ((margin < this.minMargin) || (margin > this.maxMargin))
{
string msg = string.Format("Margin must be between {0} and {1}.", this.minMargin, this.maxMargin);
return new ValidationResult(false, msg);
}
// Number is valid
return new ValidationResult(true, null);
}
}
}
En este código, la lógica de validación de una regla de validación se implementa invalidando el método Validate, que valida los datos y devuelve el objeto ValidationResult correspondiente.
Para asociar la regla de validación al control enlazado, utilice el marcado siguiente.
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.MarginsDialogBox"
xmlns:local="clr-namespace:SDKSample"
Title="Margins"
Height="190"
Width="300"
MinHeight="10"
MinWidth="300"
ResizeMode="CanResizeWithGrip"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner"
FocusManager.FocusedElement="{Binding ElementName=leftMarginTextBox}">
<Grid>
...
<Label Grid.Column="0" Grid.Row="0">Left Margin:</Label>
<TextBox Name="leftMarginTextBox" Grid.Column="1" Grid.Row="0">
<TextBox.Text>
<Binding Path="Left" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:MarginValidationRule MinMargin="0" MaxMargin="10" />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
...
</Window>
Una vez asociada la regla de validación, WPF lo aplicará automáticamente cuando se introduzcan los datos en el control enlazado. Cuando un control contenga datos no válidos, WPF mostrará un borde rojo alrededor del control no válido, como se muestra en la figura siguiente.
WPF no restringe a un usuario al control no válido hasta que haya introducido datos válidos. Ésta es una buena práctica para un cuadro de diálogo; un usuario debe poder navegar libremente por los controles de un cuadro de diálogo tanto si los datos son válidos como si no. Sin embargo, esto significa que un usuario puede introducir datos no válidos y presionar el Aceptar botón. Por esta razón, el código necesita además validar todos los controles del cuadro de diálogo cuando se presione el botón Aceptar, controlando el evento Click.
Imports System.Windows ' Window, RoutedEventArgs, IInputElement, DependencyObject
Imports System.Windows.Controls ' Validation
Imports System.Windows.Input ' Keyboard
Namespace SDKSample
Public Class MarginsDialogBox
Inherits Window
...
Private Sub okButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Don't accept the dialog box if there is invalid data
If Not Me.IsValid(Me) Then Return
...
End Sub
' Validate all dependency objects in a window
Private Function IsValid(ByVal node As DependencyObject) As Boolean
' Check if dependency object was passed and if dependency object is valid.
' NOTE: Validation.GetHasError works for controls that have validation rules attached
If ((Not node Is Nothing) AndAlso Validation.GetHasError(node)) Then
' If the dependency object is invalid, and it can receive the focus,
' set the focus
If TypeOf node Is IInputElement Then
Keyboard.Focus(DirectCast(node, IInputElement))
End If
Return False
End If
' If this dependency object is valid, check all child dependency objects
Dim subnode As Object
For Each subnode In LogicalTreeHelper.GetChildren(node)
If (TypeOf subnode Is DependencyObject AndAlso Not Me.IsValid(DirectCast(subnode, DependencyObject))) Then
' If a child dependency object is invalid, return false immediately,
' otherwise keep checking
Return False
End If
Next
' All dependency objects are valid
Return True
End Function
End Class
End Namespace
using System.Windows; // Window, RoutedEventArgs, IInputElement, DependencyObject
using System.Windows.Controls; // Validation
using System.Windows.Input; // Keyboard
namespace SDKSample
{
public partial class MarginsDialogBox : Window
{
...
void okButton_Click(object sender, RoutedEventArgs e)
{
// Don't accept the dialog box if there is invalid data
if (!IsValid(this)) return;
...
}
// Validate all dependency objects in a window
bool IsValid(DependencyObject node)
{
// Check if dependency object was passed
if (node != null)
{
// Check if dependency object is valid.
// NOTE: Validation.GetHasError works for controls that have validation rules attached
bool isValid = !Validation.GetHasError(node);
if (!isValid)
{
// If the dependency object is invalid, and it can receive the focus,
// set the focus
if (node is IInputElement) Keyboard.Focus((IInputElement)node);
return false;
}
}
// If this dependency object is valid, check all child dependency objects
foreach (object subnode in LogicalTreeHelper.GetChildren(node))
{
if (subnode is DependencyObject)
{
// If a child dependency object is invalid, return false immediately,
// otherwise keep checking
if (IsValid((DependencyObject)subnode) == false) return false;
}
}
// All dependency objects are valid
return true;
}
}
}
Este código enumera todos los objetos de dependencia de una ventana y, si hay alguno que no es válido (si devuelve GetHasError, el control no válido obtiene el foco, el método IsValid devuelve false y la ventana se considera no válida.
Cuando un cuadro de diálogo es válido, se puede cerrar y devolver sin ningún riesgo. Como parte del proceso de retorno, debe devolver un resultado a la función que realiza la llamada.
Establecer el resultado del diálogo modal
Abrir un cuadro de diálogo mediante ShowDialog es fundamentalmente como llamar a un método: el código que abrió el cuadro de diálogo mediante ShowDialog espera hasta que vuelva ShowDialog. Cuando vuelve ShowDialog, el código que lo llamó debe decidir si continúa o detiene el procesamiento, según si el usuario presionó el botón Aceptar o el botón Cancelar. Para facilitar esta decisión, el cuadro de diálogo debe devolver la opción del usuario como un valor Boolean que se devuelve desde el método ShowDialog.
Cuando se hace clic en el botón Aceptar, ShowDialog debe devolver true. Esto se logra estableciendo la propiedad DialogResult del cuadro de diálogo al hacer clic en el botón Aceptar.
Tenga en cuenta que establecer la propiedad DialogResult también hace que la ventana se cierre automáticamente, los que elimina la necesidad de llamar explícitamente a Close.
Cuando se hace clic en el botón Cancelar, ShowDialog debe devolver false, que también requiere que se establezca la propiedad DialogResult.
Imports System.Windows ' Window, RoutedEventArgs, IInputElement, DependencyObject
Imports System.Windows.Controls ' Validation
Imports System.Windows.Input ' Keyboard
Namespace SDKSample
Public Class MarginsDialogBox
Inherits Window
...
Private Sub cancelButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
' Dialog box canceled
Me.DialogResult = False
End Sub
...
End Class
End Namespace
using System.Windows; // Window, RoutedEventArgs, IInputElement, DependencyObject
using System.Windows.Controls; // Validation
using System.Windows.Input; // Keyboard
namespace SDKSample
{
public partial class MarginsDialogBox : Window
{
...
void cancelButton_Click(object sender, RoutedEventArgs e)
{
// Dialog box canceled
this.DialogResult = false;
}
...
}
}
Cuando la propiedad IsCancel de un botón se establece en true y el usuario presiona el botón Cancelar o la tecla ESC, DialogResult se establece automáticamente en false. El marcado siguiente tiene el mismo efecto que el código anterior, sin la necesidad de administrar el evento Click.
<Button Name="cancelButton" IsCancel="True">Cancel</Button>
Un cuadro de diálogo devuelve automáticamente true cuando un usuario presiona el botón Cerrar de la barra de título o elige el elemento de menú Cerrar en el menú Sistema.
Procesar datos devueltos desde un cuadro de diálogo modal
Cuando un cuadro de diálogo establece DialogResult, la función que lo abrió puede obtener el resultado del cuadro de diálogo inspeccionando la propiedad DialogResult cuando vuelve ShowDialog.
Imports System ' EventArgs
Imports System.ComponentModel ' CancelEventArgs
Imports System.Windows ' Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls ' TextChangedEventArgs
Imports Microsoft.Win32 ' OpenFileDialog
Namespace SDKSample
Public Class MainWindow
Inherits Window
...
Private Sub formatMarginsMenuItem_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
...
' Process data entered by user if dialog box is accepted
If (dlg.DialogResult.GetValueOrDefault = True) Then
Me.documentTextBox.Margin = dlg.DocumentMargin
End If
End Sub
...
End Class
End Namespace
using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextChangedEventArgs
using Microsoft.Win32; // OpenFileDialog
namespace SDKSample
{
public partial class MainWindow : Window
{
...
void formatMarginsMenuItem_Click(object sender, RoutedEventArgs e)
{
...
// Process data entered by user if dialog box is accepted
if (dlg.DialogResult == true)
{
// Update fonts
this.documentTextBox.Margin = dlg.DocumentMargin;
}
}
...
}
}
Si el resultado del diálogo es true, la función lo utiliza como indicación para recuperar y procesar los datos proporcionados por el usuario.
Nota
Una vez que vuelve ShowDialog, no se puede volver a abrir el cuadro de diálogo. En su lugar, debe crear una nueva instancia.
Si el resultado del diálogo es false, la función debe finalizar el procesamiento correctamente.
Crear un cuadro de diálogo personalizado no modal
Un cuadro de diálogo no modal, tal como el cuadro de diálogo Buscar que se muestra en la figura siguiente, tiene el mismo aspecto fundamental que un cuadro de diálogo modal.
Sin embargo, su comportamiento es ligeramente diferente, como se describe en las secciones siguientes.
Abrir un cuadro de diálogo no modal
Un cuadro de diálogo no modal se abre llamando al método Show.
<!--Main Window-->
Imports System ' EventArgs
Imports System.ComponentModel ' CancelEventArgs
Imports System.Windows ' Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls ' TextChangedEventArgs
Imports Microsoft.Win32 ' OpenFileDialog
Namespace SDKSample
Public Class MainWindow
Inherits Window
...
Private Sub editFindMenuItem_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Dim dlg As New FindDialogBox(Me.documentTextBox)
dlg.Owner = Me
AddHandler dlg.TextFound, New TextFoundEventHandler(AddressOf Me.dlg_TextFound)
dlg.Show()
End Sub
using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextChangedEventArgs
using Microsoft.Win32; // OpenFileDialog
namespace SDKSample
{
public partial class MainWindow : Window
{
...
void editFindMenuItem_Click(object sender, RoutedEventArgs e)
{
// Instantiate the dialog box
FindDialogBox dlg = new FindDialogBox(this.documentTextBox);
// Configure the dialog box
dlg.Owner = this;
dlg.TextFound += new TextFoundEventHandler(dlg_TextFound);
// Open the dialog box modally
dlg.Show();
}
...
}
}
A diferencia de ShowDialog, Show vuelve inmediatamente. Por consiguiente, la ventana que realiza la llamada no puede distinguir cuándo se cierra el cuadro de diálogo no modal y, en consecuencia, no sabe cuándo comprobar los resultados del cuadro de diálogo o recibir los datos del cuadro de diálogo para continuar el procesamiento. En su lugar, el cuadro de diálogo debe crear una manera alternativa de devolver datos a la ventana que realiza la llamada para el procesamiento.
Procesar datos devueltos desde un cuadro de diálogo no modal
En este ejemplo, FindDialogBox puede devolver uno o más resultados de búsqueda a la ventana principal, según el texto que se esté buscando, sin ninguna frecuencia concreta. Como con un cuadro de diálogo modal, un cuadro de diálogo no modal puede devolver resultados mediante propiedades. Sin embargo, la ventana que posee el cuadro de diálogo necesita saber cuándo debe comprobar esas propiedades. Una manera de habilitar esto es que el cuadro de diálogo implemente un evento que se produzca siempre que se encuentre el texto. FindDialogBox implementa TextFoundEvent para este propósito, que requiere primero un delegado.
Namespace SDKSample
Public Delegate Sub TextFoundEventHandler(ByVal sender As Object, ByVal e As EventArgs)
End Namespace
using System;
namespace SDKSample
{
public delegate void TextFoundEventHandler(object sender, EventArgs e);
}
Con el delegado TextFoundEventHandler, FindDialogBox implementa TextFoundEvent.
Imports System ' EventArgs
Imports System.Windows ' Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls ' TextBox, TextChangedEventArgs
Imports System.Text.RegularExpressions ' Regex
Namespace SDKSample
Public Class FindDialogBox
Inherits Window
Public Event TextFound As TextFoundEventHandler
Protected Overridable Sub OnTextFound()
RaiseEvent TextFound(Me, EventArgs.Empty)
End Sub
...
End Class
End Namespace
using System; // EventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextBox, TextChangedEventArgs
using System.Text.RegularExpressions; // Regex
namespace SDKSample
{
public partial class FindDialogBox : Window
{
public event TextFoundEventHandler TextFound;
protected virtual void OnTextFound()
{
TextFoundEventHandler textFound = this.TextFound;
if (textFound != null) textFound(this, EventArgs.Empty);
}
...
}
}
Por consiguiente, Find puede provocar el evento cuando se encuentra un resultado de búsqueda.
Imports System ' EventArgs
Imports System.Windows ' Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls ' TextBox, TextChangedEventArgs
Imports System.Text.RegularExpressions ' Regex
Namespace SDKSample
Public Class FindDialogBox
Inherits Window
...
Private Sub findNextButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
...
Me.Index = match.Index
Me.Length = match.Length
RaiseEvent TextFound(Me, EventArgs.Empty)
...
End Sub
...
End Class
End Namespace
using System; // EventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextBox, TextChangedEventArgs
using System.Text.RegularExpressions; // Regex
namespace SDKSample
{
public partial class FindDialogBox : Window
{
...
void findNextButton_Click(object sender, RoutedEventArgs e)
{
...
// Text found
this.index = match.Index;
this.length = match.Length;
OnTextFound();
...
}
...
}
}
La ventana propietaria necesita entonces registrarse con este evento y administrarlo.
Imports System ' EventArgs
Imports System.ComponentModel ' CancelEventArgs
Imports System.Windows ' Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls ' TextChangedEventArgs
Imports Microsoft.Win32 ' OpenFileDialog
Namespace SDKSample
Public Class MainWindow
Inherits Window
...
Private Sub dlg_TextFound(ByVal sender As Object, ByVal e As EventArgs)
Dim dlg As FindDialogBox = DirectCast(sender, FindDialogBox)
Me.documentTextBox.Select(dlg.Index, dlg.Length)
Me.documentTextBox.Focus()
End Sub
End Class
End Namespace
using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextChangedEventArgs
using Microsoft.Win32; // OpenFileDialog
namespace SDKSample
{
public partial class MainWindow : Window
{
...
void dlg_TextFound(object sender, EventArgs e)
{
// Get the find dialog box that raised the event
FindDialogBox dlg = (FindDialogBox)sender;
// Get find results and select found text
this.documentTextBox.Select(dlg.Index, dlg.Length);
this.documentTextBox.Focus();
}
}
}
Cerrar un cuadro de diálogo no modal
Dado que no es necesario establecer DialogResult, un diálogo no modal se puede cerrar utilizando los mecanismos proporcionados por el sistema, que incluyen los siguientes:
Hacer clic en el botón Cerrar en la barra de título.
Presionar ALT + F4.
Elegir Cerrar en el menú Sistema.
Como alternativa, el código puede llamar a Close cuando se haga clic en el botón Cerrar.
Imports System ' EventArgs
Imports System.Windows ' Window, MessageBoxXxx, RoutedEventArgs
Imports System.Windows.Controls ' TextBox, TextChangedEventArgs
Imports System.Text.RegularExpressions ' Regex
Namespace SDKSample
Public Class FindDialogBox
Inherits Window
...
Private Sub closeButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
MyBase.Close()
End Sub
End Class
End Namespace
using System; // EventArgs
using System.Windows; // Window, MessageBoxXxx, RoutedEventArgs
using System.Windows.Controls; // TextBox, TextChangedEventArgs
using System.Text.RegularExpressions; // Regex
namespace SDKSample
{
public partial class FindDialogBox : Window
{
...
void closeButton_Click(object sender, RoutedEventArgs e)
{
// Close dialog box
this.Close();
}
}
}
Vea también
Tareas
Ejemplo ColorPicker Custom Control