Zgadzam się, że używanie usługi do wyświetlania okna dialogowego zgodnie ze wzorcem MVVM jest najprostszym rozwiązaniem. Ale też zadałem sobie pytanie, czy istnieją 3 zespoły w moim projekcie Model, ViewModel, View i zgodnie z montażem modeli MVVM ViewModel ma odniesienie do Modelu, a View to zarówno Model, jak i ViewModel gdzie powinienem umieścić klasę DialogService? Jeśli umieścę jeden w zespole ViewModel - nie mam szans na utworzenie instancji DialogView; z drugiej strony, jeśli umieszczę DialogService w zestawie View, jak powinienem wstrzyknąć go w moją klasę ViewModel?
Tak, chciałbym recoment przyjrzeć Advanced MVVM scenarios with Prismczęści: Korzystanie Interaction Zamówienie Przedmioty
Jako przykład takiego podejścia:
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 poleceń
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>
Dziękuję za odpowiedź. Czy mógłbyś wyjaśnić poniższy scenariusz? Załóżmy, że wyświetlasz model widoku w oknie dialogowym Dialog Window z komendami Zapisz i Anuluj. Gdy użytkownik kliknie przycisk Zapisz w widoku (powiązany z poleceniem SaveCommand), może być konieczne przeprowadzenie sprawdzania poprawności i zapisanie konfiguracji, tylko jeśli zakończy się pomyślnie, okno dialogowe zostanie zamknięte. Nie mogę się zorientować, jak maszyna wirtualna ustawi DialogResult widoku (dlatego zamknięcie okna dialogowego). Jeszcze raz dziękuję. – Oll
Istnieje wiele sposobów na to, aby maszyna wirtualna mogła wchodzić w interakcje z widokiem bez przerywania abstrakcji. Na przykład klasa bazowa widoku okna dialogowego zazwyczaj ma pewne podstawowe właściwości i metody, dzięki którym okna dialogowe wyświetlania są nieco łatwiejsze (zazwyczaj mam interfejs dla okna dialogowego viewmodel, który zawiera rzeczy takie jak metoda, która ma działać przy obciążeniu widoku, a także jako wynik dialogu, polecenia commit/abort, itp.). Łatwym sposobem przekonania viewmodelu do zamknięcia widoku jest ujawnienie właściwości (na przykład CanClose). – Egor
Następnie utwórz odpowiednią właściwość zależności w oknie dialogowym, a gdy zmieni się format danych, ustaw powiązanie między tymi dwoma - w ten sposób możesz obsłużyć dowolną logikę w zmienionym module obsługi zdarzeń powiązanej. Z drugiej strony, jeszcze łatwiej jest po prostu wyświetlić zdarzenie "close" w oknie dialogowym viewmodel, aw oknie dialogowym kontekst danych kontekstu zmieniony handler subskrybować to zdarzenie, program obsługi może przypisać odpowiedni wynik dialogu i zamknąć okno. – Egor