Ich bin einverstanden, dass die Verwendung von Service zur Anzeige von Dialog nach MVVM-Muster die einfachste Lösung ist. Aber, ich fragte mich auch, ob es drei Assemblys in meinem Projekt Model, ViewModel, View und nach MVVM Muster Assembly ViewModel hat einen Verweis auf Model, und View zu Model und ViewModel wo sollte ich DialogService-Klasse? Wenn ich einen in die ViewModel-Assembly stelle, habe ich keine Chance, eine DialogView-Instanz zu erstellen. Auf der anderen Seite, wenn ich DialogService in der View-Assembly platzieren möchte, wie sollte ich es in meine ViewModel-Klasse einfügen?
Also, ich würde Blick auf Advanced MVVM scenarios with PrismTeil recoment: Mit Interaktion Anfrage Objekte
Als Beispiel für diesen Ansatz:
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>());
}
}
CreateUserStory Befehl
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>
Danke für die Antwort. Könnten Sie bitte das folgende Szenario erläutern? Angenommen, Sie zeigen ein Ansichtenmodell im Dialogfenster mit den Befehlen Speichern und Abbrechen an. Wenn der Benutzer in der Ansicht auf Speichern klickt (an den Befehl SaveCommand gebunden), möchten Sie vielleicht eine Überprüfung durchführen und die Konfiguration speichern. Nur wenn dies erfolgreich ist, wird der Dialog geschlossen. Ich kann anscheinend nicht verstehen, wie die VM das DialogResult der Ansicht einstellen würde (daher den Dialog schließen). Danke nochmal. – Oll
Es gibt viele Möglichkeiten, die VM mit der Ansicht zu interagieren, ohne die Abstraktion zu unterbrechen. Zum Beispiel hat die Basisklasse des Dialogansichtsmodells in der Regel einige Basiseigenschaften und Methoden, um das Anzeigen von Dialogen etwas einfacher zu machen (Ich habe normalerweise eine Schnittstelle für ein Dialoganzeigemodell, das Dinge wie eine Methode enthält, die auch beim Laden von Ansichten ausgeführt werden soll als das Ergebnis des Dialogs, Befehle commit/abort, etc). Eine einfache Möglichkeit, das Ansichtsmodell dazu zu bringen, die Ansicht zum Schließen anzuweisen, besteht darin, eine Eigenschaft verfügbar zu machen (z. B. CanClose). – Egor
Erstellen Sie dann in Ihrem Dialogfeld eine entsprechende Abhängigkeitseigenschaft, und wenn die Änderungen des Datenkontexts eine Bindung zwischen den beiden festlegen, können Sie mit jeder Logik im geänderten Ereignishandler Ihrer gebundenen Eigenschaft umgehen. Andererseits ist es noch einfacher, ein "close" -Ereignis in Ihrem Dialog-ViewModel einfach zu exponieren, und im Dialog-Datenkontext ändert der Handler dieses Ereignis, der Handler kann das entsprechende Dialog-Ergebnis zuweisen und das Fenster schließen. – Egor