Necesito crear un diálogo / indicador que incluya TextBox para la entrada del usuario. Mi problema es, ¿cómo obtener el texto después de haber confirmado el diálogo? Por lo general, haría una clase para esto que guardaría el texto en una propiedad. Sin embargo, quiero diseñar el cuadro de diálogo usando XAML. Entonces, de alguna manera tendría que extender el código XAML para guardar el contenido del TextBox en una propiedad, pero supongo que eso no es posible con XAML puro. ¿Cuál sería la mejor manera de darme cuenta de lo que me gustaría hacer? ¿Cómo crear un cuadro de diálogo que se pueda definir desde XAML pero que de alguna manera pueda devolver la entrada? ¡Gracias por cualquier pista!
84
Solo agrego un método estático para llamarlo como un MessageBox:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" x:Class="utils.PromptDialog" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" WindowStartupLocation="CenterScreen" SizeToContent="WidthAndHeight" MinWidth="300" MinHeight="100" WindowStyle="SingleBorderWindow" ResizeMode="CanMinimize"> <StackPanel Margin="5"> <TextBlock Name="txtQuestion" Margin="5"/> <TextBox Name="txtResponse" Margin="5"/> <PasswordBox Name="txtPasswordResponse" /> <StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Right"> <Button Content="_Ok" IsDefault="True" Margin="5" Name="btnOk" Click="btnOk_Click" /> <Button Content="_Cancel" IsCancel="True" Margin="5" Name="btnCancel" Click="btnCancel_Click" /> </StackPanel> </StackPanel> </Window>
Y el código detrás:
Entonces puedes llamarlo así:
fuente
MessageBox
método estático de estilo. ¡Código conciso y reutilizable!Gran respuesta de Josh, todo el mérito para él, sin embargo, lo modifiqué ligeramente a esto:
MyDialog Xaml
<StackPanel Margin="5,5,5,5"> <TextBlock Name="TitleTextBox" Margin="0,0,0,10" /> <TextBox Name="InputTextBox" Padding="3,3,3,3" /> <Grid Margin="0,10,0,0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Button Name="BtnOk" Content="OK" Grid.Column="0" Margin="0,0,5,0" Padding="8" Click="BtnOk_Click" /> <Button Name="BtnCancel" Content="Cancel" Grid.Column="1" Margin="5,0,0,0" Padding="8" Click="BtnCancel_Click" /> </Grid> </StackPanel>
Código subyacente de MyDialog
Y llámalo en otro lugar
fuente
WindowStyle="ToolWindow"
en la ventana hace que se vea aún mejor. TambiénWindowStartupLocation="CenterOwner"
y lodialog.Owner = this;
coloca en el centro de la ventana principalNo necesita NINGUNA de estas otras respuestas sofisticadas. A continuación se muestra un ejemplo simplista que no tiene todo el
Margin
,Height
,Width
propiedades establecidas en el XAML, pero debe ser suficiente para mostrar cómo hacer esto a un nivel básico.XAML
Construir una
Window
página como lo haría normalmente y añadir sus campos para que, digamos unaLabel
yTextBox
de control dentro de unaStackPanel
:<StackPanel Orientation="Horizontal"> <Label Name="lblUser" Content="User Name:" /> <TextBox Name="txtUser" /> </StackPanel>
Luego cree un estándar
Button
para Envío ("Aceptar" o "Enviar") y un botón "Cancelar" si lo desea:<StackPanel Orientation="Horizontal"> <Button Name="btnSubmit" Click="btnSubmit_Click" Content="Submit" /> <Button Name="btnCancel" Click="btnCancel_Click" Content="Cancel" /> </StackPanel>
Código subyacente
Agregará las
Click
funciones del controlador de eventos en el código subyacente, pero cuando vaya allí, primero declare una variable pública donde almacenará el valor del cuadro de texto:Luego, para las funciones del controlador de eventos (haga clic
Click
con el botón derecho en la función en el botón XAML, seleccione "Ir a la definición", la creará para usted), necesita una verificación para ver si su casilla está vacía. Lo almacena en su variable si no es así, y cierra su ventana:Llamarlo desde otra página
Estás pensando, si cierro mi ventana con eso
this.Close()
ahí arriba, mi valor se ha ido, ¿verdad? ¡¡NO!! Encontré esto en otro sitio: http://www.dreamincode.net/forums/topic/359208-wpf-how-to-make-simple-popup-window-for-input/Tenían un ejemplo similar a este (lo limpié un poco) de cómo abrir su
Window
de otro y recuperar los valores:Botón Cancelar
Estás pensando, bueno, ¿qué pasa con el botón Cancelar? Así que simplemente agregamos otra variable pública en nuestro código subyacente de la ventana emergente:
E incluyamos nuestro
btnCancel_Click
controlador de eventos y hagamos un cambio enbtnSubmit_Click
:private void btnCancel_Click(object sender, RoutedEventArgs e) { cancelled = true; strUserName = String.Empty; this.Close(); } private void btnSubmit_Click(object sender, RoutedEventArgs e) { if (!String.IsNullOrEmpty(txtUser.Text)) { strUserName = txtUser.Text; cancelled = false; // <-- I add this in here, just in case this.Close(); } else MessageBox.Show("Must provide a user name in the textbox."); }
Y luego leemos esa variable en nuestro
MainWindow
btnOpenPopup_Click
evento:Respuesta larga, pero quería mostrar lo fácil que es usar
public static
variables. NoDialogResult
, sin valores devueltos, nada. Simplemente abra la ventana, almacene sus valores con los eventos de botón en la ventana emergente, luego recupérelos en la función de la ventana principal.fuente
DialogResult
en WPF, esMessageBoxResult
que he encontrado sólo funciona de botones estándar en unMessageBox.Show()
diálogo - no uno de un diálogo personalizado se muestra a través de.ShowDialog()
- y sólo puede consulta de los operadores de la norma,MessageBoxResult.OK
,MessageBoxResult.Cancel
, "Sí" , "No", etc., no booleanos ni valores personalizados. 3)IsCancel
requeriría almacenarlo en un booleano y enviarlo de vuelta, de todos modos, por lo que esta era una solución única para todos.