c# - programacion - MahApps MessageBoxes utilizando MVVM
que es mvvm en programacion (3)
Pregunta simple para MahApps Merry Men. Implementé una aplicación usando sus excelentes controles estilo metro utilizando Caliburn.Micro para las cosas de MVVM. Los nuevos cuadros de diálogo de mensaje se ven muy bien, pero actualmente no hay una forma clara de iniciar estos diálogos sin escribir mi propio contenedor (que no estoy en contra). Sin embargo, ¿se ha hecho esto o hay algo que me falta para que pueda invocar un cuadro de mensaje desde un modelo de vista sin ningún problema?
Gracias por tu tiempo.
Creé un contenedor para llamar al cuadro de diálogo MahApps.Metro, porque estaba teniendo el mismo problema con mi proyecto MVVM. Tuve que crear una lista de ventanas abiertas, que la primera ventana siempre será mi MainWindow.
Aquí está mi código DialogService
:
public async Task<MessageDialogResult> ShowMessage(string message, MessageDialogStyle dialogStyle)
{
var metroWindow = (_openedViews.First() as MetroWindow);
metroWindow.MetroDialogOptions.ColorScheme = MetroDialogColorScheme.Accented;
return await metroWindow.ShowMessageAsync("MY TITLE", message, dialogStyle, metroWindow.MetroDialogOptions);
}
Este código se puede usar para mostrar diálogos con o sin resultado. Puede observar que su resultado es una Task<MessageDialogResult>
, por lo que si desea obtener el resultado, puede hacerlo así en su ViewModel:
MessageDialogResult result = await _dialog.ShowMessage("SOME MESSAGE HERE", MessageDialogStyle.AffirmativeAndNegative).ConfigureAwait(false);
if (result == MessageDialogResult.Affirmative)
{
//Do something
}
Por cierto, si el método que llama a ShowMessage()
necesita un resultado, DEBE poner async
en la asignación, de lo contrario no funcionará. (si solo desea mostrar un diálogo de mensaje, no es necesario).
Mi proyecto está usando Framework 4.0, y solo puedo usar async/await
debido al paquete que tuve que instalar desde NuGet. Puede acceder a este enlace para obtener la documentación de MSDN de este paquete, y puede descargar el paquete aquí .
Espero que haya resuelto tu problema.
EDITAR:
Implementé un método en mi DialogService
para abrir cualquier ventana desde cualquier ViewModel. Este método usa Microsoft Unity
marco Microsoft Unity
para crear una instancia de mi objeto, y luego llamo a Show()
para que se abra solo. Antes de una llamada Show()
, agrego esta ventana en una lista.
Ver mi código:
public void ShowView<T>(params ParameterOverride[] parameter)
{
var window = UnityServiceConfigurator.Instance.Container.Resolve<T>(parameter) as MetroWindow;
if (window != null)
{
if (Application.Current.MainWindow != window)
{
window.Owner = Application.Current.MainWindow;
var ownerMetroWindow = (window.Owner as MetroWindow);
if (!ownerMetroWindow.IsOverlayVisible())
ownerMetroWindow.ShowOverlayAsync();
}
if (!_openedViews.Contains(window))
_openedViews.Add(window);
window.Show();
}
}
Así es como llamo desde mi ViewModel:
_dialog.ShowView<MyView>();
Si solo tiene una ventana en todo el software, puede guardar su referencia y usarla para mostrar ShowMessageAsync()
sin necesidad de crear una lista solo para usar First. Me gusta esto:
var metroWindow = (Application.Current.MainWindow as MetroWindow);
Si solo tiene una instancia de la ventana que se muestra, puede intentar algo como esto:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Caliburn.Micro;
using MahApps.Metro.Controls;
using MahApps.Metro.Controls.Dialogs;
namespace Busyboy
{
[Export(typeof(IShell))]
class MainViewModel : PropertyChangedBase, IShell
{
public void StartPomodoro()
{
var mainview0 = System.Windows.Application.Current.Windows.OfType<MainView>().FirstOrDefault();
mainview0.ShowInputAsync("New Pomodoro", "Enter a name for new pomodoro session.");
}
}
}
Y, debe tener una forma de identificar cada ventana para que pueda filtrar las ventanas. Tenga en cuenta la importación "Metro.Controls.Dialogs" que contiene las extensiones.
A partir de 1.1.3-ALPHA * (para convertirse en 1.2.0) MahApps proporciona un ayudante para iniciar diálogos desde una máquina virtual, que funciona en una configuración de múltiples ventanas:
1) Use una propiedad adjunta en su ventana para registrar su modelo de vista con el subsistema de diálogo.
Suponiendo que el DataContext de su Vista está configurado en el modelo de vista desde el que desea iniciar el diálogo, agregue estos atributos:
<Controls:MetroWindow
xmlns:Dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
Dialog:DialogParticipation.Register="{Binding}">
2) Asignar / inyectar DialogCoordinator:
new MainWindowViewModel(DialogCoordinator.Instance);
3) Muestre su diálogo desde el modelo de vista. Use "this" como contexto para que MahApps pueda casar su modelo de vista con la ventana correcta:
_dialogCoordinator.ShowMessageAsync(this, "Message from VM", "MVVM based dialogs!")