Estoy de acuerdo, que el uso del servicio para mostrar el diálogo según el patrón MVVM es la solución más simple. Pero, también me pregunté a mí mismo si hay 3 ensambles en mi modelo de proyecto, ViewModel, View y de acuerdo con el ensamblaje de patrones de MVVM ViewModel tiene una referencia a Model y View a Model y ViewModel, ¿dónde debería colocar la clase DialogService? Si coloco uno en el ensamblado de ViewModel, no tengo posibilidades de crear la instancia de DialogView; por otro lado, si ubicaré DialogService en el ensamblaje de Vista, ¿cómo debería inyectarlo en mi clase ViewModel?
lo tanto, me recoment vistazo a Advanced MVVM scenarios with PrismParte: Uso de solicitudes Interacción Objetos
Como ejemplo de este enfoque:
DialogViewModelBase
public abstract class DialogViewModelBase : ViewModelBase
{
private ICommand _ok;
public ICommand Ok
{
get { return _ok ?? (_ok = new DelegateCommand(OkExecute, CanOkExecute)); }
}
protected virtual bool CanOkExecute()
{
return true;
}
protected virtual void OkExecute()
{
_isSaved = true;
Close = true;
}
private ICommand _cancel;
public ICommand Cancel
{
get
{
return _cancel ?? (_cancel = new DelegateCommand(CancelExecute, CanCancelExecute));
}
}
protected virtual bool CanCancelExecute()
{
return true;
}
protected virtual void CancelExecute()
{
Close = true;
}
private bool _isSaved = false;
public bool IsSaved
{
get { return _isSaved; }
}
private bool _close = false;
public bool Close
{
get { return _close; }
set
{
_close = value;
RaisePropertyChanged(() => Close);
}
}
}
CreateUserStoryViewModel:
public class CreateUserStoryViewModel : DialogViewModelBase
{
private string _name = String.Empty;
public string Name
{
get { return _name; }
set
{
_name = value;
RaisePropertyChanged(() => Name);
}
}
}
CreateUserStoryRequest
private InteractionRequest<Notification> _createUserStoryRequest;
public InteractionRequest<Notification> CreateUserStoryRequest
{
get
{
return _createUserStoryRequest ?? (_createUserStoryRequest = new InteractionRequest<Notification>());
}
}
Comando CreateUserStory
private void CreateUserStoryExecute()
{
CreateUserStoryRequest.Raise(new Notification()
{
Content = new CreateUserStoryViewModel(),
Title = "Create User Story"
},
notification =>
{
CreateUserStoryViewModel createUserStoryViewModel =
(CreateUserStoryViewModel)notification.Content;
if (createUserStoryViewModel.IsSaved)
{
_domainContext.CreateUserStory(
new UserStory(){ Name = createUserStoryViewModel.Name, });
}
});
}
XAML:
<!--where xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ir="clr-namespace:Microsoft.Practices.Prism.Interactivity.InteractionRequest;assembly=Microsoft.Practices.Prism.Interactivity"-->
<i:Interaction.Triggers>
<ir:InteractionRequestTrigger SourceObject="{Binding CreateUserStoryRequest}">
<ir:PopupChildWindowAction>
<ir:PopupChildWindowAction.ChildWindow>
<view:CreateUserStory />
</ir:PopupChildWindowAction.ChildWindow>
</ir:PopupChildWindowAction>
</ir:InteractionRequestTrigger>
</i:Interaction.Triggers>
Gracias por la respuesta. ¿Podría aclarar el escenario a continuación, por favor? Supongamos que muestra un modelo de vista en el DialogWindow con los comandos Guardar y Cancelar. Cuando el usuario hace clic en Guardar en la vista (vinculado a SaveCommand), quizás desee ejecutar alguna validación y guardar la configuración, solo si el diálogo se cierra correctamente. Parece que no entiendo cómo la máquina virtual establecería el DialogResult de la vista (por lo tanto, cerrará el cuadro de diálogo). Gracias de nuevo. – Oll
Hay muchas maneras de hacer que la VM interactúe con la vista sin romper la abstracción. Por ejemplo, la clase base del modelo de vista de diálogo tiene típicamente algunas propiedades y métodos básicos para hacer que mostrar diálogos sea un poco más fácil (normalmente tengo una interfaz para un modelo de vista de diálogo que incluye cosas como un método que se ejecuta en carga de vista, así como el resultado del diálogo, comandar/abortar comandos, etc.). Una manera fácil de obtener el modelo de vista para decirle a la vista que cierre es exponer una propiedad (CanClose, por ejemplo). – Egor
Luego, cree una propiedad de dependencia correspondiente en su cuadro de diálogo, y cuando los cambios en el contexto de datos establezcan un enlace entre los dos, de esa forma puede manejar cualquier lógica en el controlador de eventos modificado de su propiedad encuadernada. Por otra parte, es incluso más fácil simplemente exponer un evento "cerrado" en su modelo de vista de diálogo, y en el contexto de datos de ventana el controlador modificado se suscribe a este evento, el manejador puede asignar el resultado de diálogo apropiado y cerrar la ventana. – Egor