2010-03-02 19 views
14

Rozważam użycie MVVM i chociaż rozumiem to w przeważającej części, jest jedna rzecz, której nie mogę zrozumieć.MVVM Przekazywanie danych do okna dialogowego Wyświetl model

Wyobraź sobie, że mam kombinację Widok i ViewModel, które pokazują listę foobarów. Kiedy użytkownik wybierze foobar na liście i kliknie przycisk edycji, chcę, aby pokazał się w oknie dialogowym, aby można było go edytować. To okno dialogowe (widok) będzie mieć swój własny skojarzony ViewModel.

Rozumiem, że przycisk może być powiązany z poleceniem na liście ViewModel, ale od tego w jaki sposób mogę utworzyć instancję edytora foobar?

1) Czy muszę wysłać wiadomość z powrotem do widoku, które otworzy okno dialogowe? Jeśli tak, czy nie jest to sprzeczne z celem posiadania polecenia?

2) W jaki sposób foobar zostaje wprowadzony do edytora ViewModel? Jeśli jest to przez jego konstruktora, czy nie utrudnia to deklaracji ViewModel w XAML?

Czuję, że jest to ostatni element układanki, który uniemożliwia mi korzystanie z MVVM i naprawdę chciałbym mieć do tego dobre, oddzielone od siebie rozwiązanie.

Dzięki Matt

Odpowiedz

2

bym może to zrobić w następujący sposób:

  1. Polecenie przypisane do przycisku Edytuj uruchamia okno edycji, tworzenia niestandardowych ViewModel (VM) dla niego. Samo polecenie powinno być albo na VM albo w Modelu (nie do końca pewne).
  2. Maszyna wirtualna VM w oknie edycji Foobar otrzymuje odniesienie do Foobar w swoim konstruktorze.
  3. Foobar jest klonowany, a klon edytowany.
  4. Gdy tylko użytkownik naciśnie przycisk OK w oknie edycji foobar, wartości klonu zostaną zapisane z powrotem na oryginalnym elemencie w maszynie wirtualnej (i okno dialogowe zostanie zamknięte).

Potrzeba klonu pochodzi z faktu, że użytkownik nie chce, aby zobaczyć zmiany na liście foobar, dopóki nie zaakceptuje zmiany w oknie edycji. Jeśli jednak edycja online jest w porządku, klon nie jest potrzebny.

Zmiany są automatycznie propagowane.

PS: chociaż jestem zwolennikiem MVVM, nie jestem pewien, czy moje rozwiązanie jest zgodne z prawdą z czysto MVVM.

1

This article z codeproject pokazuje kontrolkę Dialog WPF, który robi dokładnie to, czego potrzebujesz. Powodem, dla którego ta implementacja jest konieczna, jest to, że nie można umieścić okna wewnątrz drzewa wizualnego żadnej innej kontrolki. Co oznacza, że ​​po wyjęciu z pudełka WPF nie pozwala na utworzenie okna dialogowego wewnątrz okna. Tak więc powyższy artykuł tworzy podklasę ContentControl, która tworzy okno.

W każdym razie, można umieścić to w swoim FooBarList View

<dialog:Dialog Content="{Binding Path=DialogViewModel}" /> 

upewnić się, że masz coś takiego w słowniku zasobów gdzieś:

<Style TargetType="{x:Type dialog:Dialog}"> 
<Style.Triggers> 
    <Trigger Property="HasContent" Value="True"> 
    <Setter Property="Showing" Value="True" /> 
    </Trigger> 
</Style.Triggers> 
</Style> 

i po prostu napisać coś takiego (dla WPF do pracy musisz wdrożyć INotifyPropertyChanged):

public Class FooBarListViewModel 
{ 
    IList<FooBar> FooBarList {get;set;} 
    FooBar SelectedFooBar {get;set;} 
    ViewModelBase DialogViewModel {get;set;} 

    public EditFooBar(object param) 
    { 
    DialogViewModel = FooBar; 
    } 
} 

Aby połączyć Vie W celu edycji foobar do foobar ViewModel prostu zrobić coś takiego (najlepiej Application.Resources więc globalne)

<DataTemplate DataType={x:Type vm:FooBarViewModel}> 
    <vw:FooBarView/> 
</DataTemplate> 

(lub opcjonalnie: Użyj IValueConverter konwertować uzyskać widok z ViewModel like this post shows)

A następnie gotowe. Może brzmi jak dużo, ale naprawdę bardzo cię to uwalnia.

+0

To interesujące podejście. Patrząc na przykładowy projekt, zastanawiam się, czy mam zostać ukąszony przez utratę niektórych funkcji normalnego okna (zmiana rozmiaru, modeless, itp.). Zaczynam myśleć, że warto byłoby wziąć pod uwagę projekt, który nie wymaga skomplikowanych dialogów - i może zamiast tego mieć aplikację MDI. Co sądzisz o tym? – Matt

0

Brakuje kontrolera odpowiedzialnego za przepływ roboczy ViewModels. Kontroler tworzy ViewModels i przekazuje niezbędne dane między ViewModels.

Projekt WPF Application Framework (WAF) zawiera przykładowe aplikacje, które pokazują, jak to może działać.