mvvmlight - Mostrar diálogo con el juego de herramientas MVVM Light
mvvmlight xamarin forms (4)
Deberías usar la clase Messenger
. En la View
registre un mensaje para mostrar la ventana y luego cuando necesite mostrarlo, llame al método de Send
de la clase Messenger
.
Puedes hacer algo como esto:
//do this in code behind file of your View
Messenger.Default.Register<string>(this, ShowWindow);
private void ShowWindow(string message)
{
// your logic here
}
// In the ViewModel
Messenger.Default.Send(“Some text”);
Tengo un ViewModel que necesita mostrar una ventana modal (usando ShowDialog()
) en un botón. ViewModel detecta el comando de clic, pero no quiero hacer window.ShowDialog()
dentro de mi ViewModel. Sé que hay un DialogMessage
en MVVM Light, pero se usa para mostrar cuadros de mensajes, no para ventanas modales de WPF.
¿Alguna idea sobre cómo hacer esto?
Esto es lo que uso para los diálogos personalizados con MVVM-Light Toolkit.
Primero, define estas cuatro clases en algún lugar de tu aplicación. La clase MessageBase es parte del kit de herramientas.
public class ShowChildWindowMessage : MessageBase { }
public class HideChildWindowMessage : MessageBase { }
public class DisplaySomeContentMessage : MessageBase { }
public class DisplaySomeOtherContentMessage : MessageBase { }
Segundo, necesitas un control de ventana "hijo". Crea un archivo XAML con el siguiente contenido:
<Window x:Class="ChildWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding Path=ChildWindowBinding, Source={StaticResource Locator}}"
Title="{Binding Path=CurrentContent.DisplayName}"
MinWidth="300" MinHeight="125" SizeToContent="WidthAndHeight"
ShowInTaskbar="False" WindowState="Normal" ResizeMode="NoResize"
WindowStartupLocation="CenterOwner" SnapsToDevicePixels="True">
<Grid>
<ContentPresenter Content="{Binding Path=CurrentContent}" />
</Grid>
Luego agregue lo siguiente al código subyacente de este archivo XAML:
public partial class ChildWindowView : Window
{
public ChildWindowView(Window owner)
{
InitializeComponent();
Owner = owner;
Closing += (s, e) =>
{
// window reused so just hide
e.Cancel = true;
Messenger.Default.Send(new HideChildWindowMessage());
};
}
}
Tercero, agregue lo siguiente al código subyacente de su archivo MainWindow.xaml:
public partial class MainWindowView : Window
{
private ChildWindowView m_childWindowView;
public MainWindowView()
{
InitializeComponent();
Closing += (s, e) => ViewModelLocator.CleanUp();
Loaded += (s, e) =>
{
m_childWindowView = new ChildWindowView(this);
};
Messenger.Default.Register<ShowChildWindowMessage>(this, (msg) => m_childWindowView.ShowDialog());
Messenger.Default.Register<HideChildWindowMessage>(this, (msg) => m_childWindowView.Hide());
}
}
Cuarto, define el siguiente modelo de vista:
public class ChildWindowVM : ViewModelBase
{
private ViewModelBase m_currentContent;
public ViewModelBase CurrentContent
{
get { return m_currentContent; }
set
{
m_currentContent = value;
RaisePropertyChanged("CurrentContent");
if (m_currentContent != null)
{
Messenger.Default.Send(new ShowChildWindowMessage());
}
}
}
public ChildWindowVM()
{
Messenger.Default.Register<DisplaySomeContentMessage>(this, (msg) => CurrentContent = ViewModelLocator.SomeContentVm);
Messenger.Default.Register<DisplaySomeOtherContentMessage>(this, (msg) => CurrentContent = ViewModelLocator.SomeOtherContentVm);
}
}
En quinto lugar, crea archivos XAML y ve modelos para el contenido que desea mostrar en su diálogo personalizado. En este ejemplo, mis modelos de vista de contenido se denominaron SomeContent y SomeOtherContent. Los reemplazarías con lo que quieras, por supuesto.
Finalmente, para que esto funcione, debe vincular sus modelos de vista de contenido a sus respectivos archivos XAML agregando lo siguiente a sus recursos de aplicación:
<DataTemplate DataType="{x:Type viewmodels:SomeContentVM}">
<views:SomeContentView/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:SomeOtherContentVM}">
<views:SomeOtherContentView/>
</DataTemplate>
Ahora, una vez que haya configurado todo esto, es muy fácil agregar contenido nuevo (XAML y modelos de vista) que se puede mostrar en la ventana de su hijo. Para mostrar el contenido, simplemente llame al mensaje apropiado usando la clase Messenger:
Messenger.Default.Send(new DisplaySomeContentMessage ());
Déjame saber si necesito aclarar alguna parte de esto para ti.
Para todos aquellos que desean una solución realmente simple y están de acuerdo con no-100% -clean-MVVM:
Quería abrir un cuadro de diálogo de conexión desde mi ventana principal e hice lo siguiente
Primero le di un nombre a mi MainWindow:
<Window x:Name="MainWindow">
Entonces creé un comando en mi MainWindowViewModel:
public ICommand AddInterfaceCommand
{
get
{
return new RelayCommand<Window>((parentWindow) =>
{
var wizard = new ConnectionWizard();
wizard.Owner = parentWindow;
wizard.ShowDialog();
}
}
}
Limité mi botón en la ventana principal al comando y pasé la ventana en sí (la ventana principal para el diálogo):
<Button Command="{Binding AddInterfaceCommand}" CommandParameter="{Binding ElementName=MainWindow}">Add interface</Button>
Eso es todo.
Solo advertencia: obtener valores de retorno desde el modelo de vista del diálogo podría ser difícil. No necesito esa característica.
Puede definir una interfaz y su implementación de la siguiente manera. Y, por supuesto, con el contenedor de inyección de dependencia, tiene que hacer algo como esto.
NInjectKernel.Bind<IMessageBoxService>().To<MessageBoxService>();
Tu ViewModel se verá algo como esto.
private IMessageBoxService _MBService;
public DropboxSettingsViewModel(IDropboxService dbService, IMessageBoxService mbService)
{
if (dbService == null)
throw new ArgumentNullException("IDropboxService is null");
_DropboxService = dbService;
if (mbService == null)
throw new ArgumentNullException("MessageBoxService is null");
_MBService = mbService;
}
Su método de ejecución de comando de clic sería el siguiente.
private void ConfigureDropboxExecute(object obj)
{
_MBService.Show("Error Occured Authenticating dropbox", "Dropbox Authentication", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK);
}
public interface IMessageBoxService
{
MessageBoxResult Show(string messageBoxText);
MessageBoxResult Show(string messageBoxText, string caption);
MessageBoxResult Show(Window owner, string messageBoxText);
MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button);
MessageBoxResult Show(Window owner, string messageBoxText, string caption);
MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon);
MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button);
MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult);
MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon);
MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options);
MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult);
MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options);
}
utilizando System.Windows;
public class MessageBoxService : IMessageBoxService
{
public MessageBoxResult Show(string messageBoxText)
{
return MessageBox.Show(messageBoxText);
}
public MessageBoxResult Show(Window owner, string messageBoxText)
{
return MessageBox.Show(owner, messageBoxText);
}
public MessageBoxResult Show(string messageBoxText, string caption)
{
return MessageBox.Show(messageBoxText, caption);
}
public MessageBoxResult Show(Window owner, string messageBoxText, string caption)
{
return MessageBox.Show(owner, messageBoxText, caption);
}
public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button)
{
return MessageBox.Show(messageBoxText, caption, button);
}
public MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button)
{
return MessageBox.Show(owner, messageBoxText, caption, button);
}
public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
{
return MessageBox.Show(messageBoxText, caption, button, icon);
}
public MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
{
return MessageBox.Show(owner, messageBoxText, caption, button, icon);
}
public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
{
return MessageBox.Show(messageBoxText, caption, button, icon, defaultResult);
}
public MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult)
{
return MessageBox.Show(owner, messageBoxText, caption, button, icon, defaultResult);
}
public MessageBoxResult Show(string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options)
{
return MessageBox.Show(messageBoxText, caption, button, icon, defaultResult, options);
}
public MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options)
{
return MessageBox.Show(owner, messageBoxText, caption, button, icon, defaultResult, options);
}
}