modal ejemplo dialogbox wpf mvvm triggers messagebox

wpf - ejemplo - ¿Cómo se implementó correctamente la funcionalidad MessageBox.Show() en MVVM?



showdialog c# ejemplo (11)

Tengo una aplicación WPF que llama a MessageBox.Show () en el ViewModel (para verificar si el usuario realmente quiere eliminar). Esto realmente funciona , pero va en contra de MVVM ya que ViewModel no debe determinar explícitamente lo que sucede en la Vista.

Así que ahora estoy pensando cómo puedo implementar mejor la funcionalidad MessageBox.Show () en mi aplicación MVVM, opciones:

  1. Podría tener un mensaje con el texto "¿Estás seguro ...?" junto con dos botones Sí y No en un borde en mi XAML, y crear un activador en la plantilla para que esté contraído / visible en función de ViewModelProperty llamado AreYourSureDialogueBoxIsVisible , y cuando necesite este cuadro de diálogo, asigne AreYourSureDialogueBoxIsVisible a "true ", y también manejar los dos botones a través de DelegateCommand en mi ViewModel.

  2. De alguna manera, también podría tratar de manejar esto con desencadenadores en XAML para que el botón Eliminar simplemente haga que aparezca algún elemento de Borde con el mensaje y los botones en él, y el botón Sí eliminó realmente.

Ambas soluciones parecen ser demasiado complejas para lo que solía ser un par de líneas de código con MessageBox.Show ().

¿De qué maneras ha implementado con éxito Dialogue Boxes en sus aplicaciones MVVM?


¿Qué pasa con la creación de un evento como "MessageBoxRequested" manejado en el código detrás de la Vista (de todos modos es solo código de vista, así que no veo ningún problema con tener este código en el código detrás).


De los dos que mencionas, prefiero la opción n. ° 2. El botón Eliminar en la página solo hace que aparezca "Confirmar cuadro de diálogo Eliminar". El "Diálogo de confirmación de eliminación" en realidad inicia la eliminación.

¿Has consultado las diapositivas y demostraciones de la línea de negocios WPF de Karl Shifflett? Sé que él hace algo como esto. Trataré de recordar dónde.

EDITAR: Verifique la demostración n. ° 11 "Validación de datos en MVVM" (EditContactItemsControlSelectionViewModel.DeleteCommand). Karl llama a una ventana emergente del ViewModal (¿Qué?? :-). De hecho, me gusta tu idea. Parece más fácil para la prueba unitaria.



Implementé un comportamiento que escucha un mensaje de ViewModel. Está basado en la solución Laurent Bugnion, pero como no usa código detrás y es más reutilizable, creo que es más elegante.

Compruébalo aquí


Lo lanzaría desde la máquina virtual. No quiero tener que usar el servicio de otra persona o escribir el mío solo para lanzar un mensaje.


Para ampliar la respuesta de Dean Chalk ahora que su enlace es kaput:

En el archivo App.xaml.cs conectamos el cuadro de diálogo de confirmación al modelo de vista.

protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); var confirm = (Func<string, string, bool>)((msg, capt) => MessageBox.Show(msg, capt, MessageBoxButton.YesNo) == MessageBoxResult.Yes); var window = new MainWindowView(); var viewModel = new MainWindowViewModel(confirm); window.DataContext = viewModel; ... }

En la vista (MainWindowView.xaml) tenemos un botón que llama a un comando en el ViewModel

<Button Command="{Binding Path=DeleteCommand}" />

El modelo de vista (MainWindowViewModel.cs) usa un comando de delegado para mostrar "¿Estás seguro?" diálogo y realizar la acción. En este ejemplo, es un SimpleCommand similar a this , pero cualquier implementación de ICommand debería hacer.

private readonly Func<string, string, bool> _confirm; //constructor public MainWindowViewModel(Func<string, string, bool> confirm) { _confirm = confirm; ... } #region Delete Command private SimpleCommand _deleteCommand; public ICommand DeleteCommand { get { return _deleteCommand ?? (_deleteCommand = new SimpleCommand(ExecuteDeleteCommand, CanExecuteDeleteCommand)); } } public bool CanExecuteDeleteCommand() { //put your logic here whether to allow deletes return true; } public void ExecuteDeleteCommand() { bool doDelete =_confirm("Are you sure?", "Confirm Delete"); if (doDelete) { //delete from database ... } } #endregion


Recientemente me encontré con este problema donde tuve que reemplazar el MessageBox.Show en ViewModels con algún mecanismo de cuadro de mensaje de queja completamente MVVM.

Para lograr esto, utilicé InteractionRequest<Notification> y InteractionRequest<Confirmation> junto con desencadenadores de interacción y escribí mis propias vistas para el cuadro de mensaje.

Lo que he implementado se publica here


Servicios al rescate Usar Onyx (descargo de responsabilidad, soy el autor) es tan fácil como:

public void Foo() { IDisplayMessage dm = this.View.GetService<IDisplayMessage>(); dm.Show("Hello, world!"); }

En una aplicación en ejecución, esto llamará indirectamente a MessageBox.Show ("¡Hola, mundo!"). Al probar, el servicio IDisplayMessage se puede burlar y proporcionar al ViewModel para que haga lo que quiera durante la prueba.


Simplemente creo una interfaz (IMessageDisplay o similar) que se inyecta en la VM, y tiene métodos como un MessageBox (ShowMessage () etc.). Puedes implementar eso usando un mensaje estándar, o algo más específico de WPF (yo uso este en CodePlex, alguien llamado Prajeesh).

De esa forma todo está separado y comprobable.



Por si acaso alguien más sigue leyendo e insatisfecho:

Solo quería manejar MessageBoxes tipo ''notificación'' (es decir, no me importa DialogResult ), pero el problema que tengo con la mayoría de las soluciones sobre las que he leído es que parecen forzarlo indirectamente a elegir su implementación de View ( es decir, actualmente tengo un MessageBox.Show , pero si luego decido simplemente jugar con la visibilidad de un panel oculto directamente en mi View, eso no se INotification muy bien con una interfaz INotification transferida al ViewModel).

Así que fui rápido y sucio:

ViewModel tiene una propiedad string NotificationMessage , con cambios notificados a PropertyChanged .

La Vista se suscribe a PropertyChanged , y si ve que la propiedad NotificationMessage llega, hace lo que quiera.

OK, entonces esto significa que la Vista tiene código subyacente, y el nombre de PropertyChanged está codificado, pero de todos modos estaría codificado en el XAML. Y significa que evito todas las cosas, como los convertidores de Visibilidad, y las propiedades para decir si la notificación sigue siendo visible o no.

(Es cierto que esto es solo para un caso de uso limitado (disparar y olvidar), no he pensado mucho sobre cómo podría extenderlo).