Szukaj na tym blogu

sobota, 27 listopada 2010

Przegląd PRISM 4 – część 4

W tej części będzie trochę nietypowo.

Dla przypomnienia, zaznaczam, że cały przegląd PRISM 4 oparty jest o ebook’a pt. "Developers Guide to Microsoft Prism. Building MVVM and Modular Applications with WPF and Silverlight"
Część 4 dotyczy najbardziej oczekiwanych przeze mnie rozdziałów „Implementing the MVVM pattern” oraz „Advanced MVVM Scenarios”. Ponieważ w tej części książki, autor opisał założenia wzorca MVVM, które są opisane w moich wcześniejszych postach, posłużę się odwołaniem do nich przy opisie poszczególnych działów będących częścią wymienionych powyżej rozdziałów.

Implementing the MVVM pattern
Class Responsibilities and Characteristics


W tej części znajdziemy opis wzorca projektowego MVVM. Zainteresowanych odsyłam do posta „Dziennik Zdrowej Diety – Wzorzec MVVM – Koncepcja”

Class interactions
Część ta opisuje mechanizm Bindowania oraz interakcję pomiędzy View, a ViewModel’em za pomocą interfejsów INotifyPropertyChanged, INotifyCollectionChanged, ICollectionView, Commanding, IDataError, INotifyDataErrorInfo.

Sposób wykorzystania pierwszych dwóch interfejsów znajdziecie również w poście „Dziennik Zdrowej Diety – Wzorzec MVVM – Koncepcja” . Mechanizm Commandingu jest przedstawiony w poście „Dziennik Zdrowej Diety – Wzorzec MVVM – Commanding”

Poniżej przedstawię możliwości jakie daje nam interfejs ICollectionView oraz DelegateCommand będący PRISM’ową implementacją interfejsu ICommand.

ICollectionView to interfejs, który umożliwia nam sortowanie, filtrowanie, grupowanie oraz śledzenie aktualnie zaznaczonego elementu z kolekcji. Jest to bardzo pomocne z punktu widzenia MVVM ponieważ otrzymujemy dosyć bogatą funkcjonalność operacji na kolekcjach po stronie ViewModel.
PagedCollectionView jest klasą, która w Silverlight (w WPF jest to klasa ListCollectionView) implementuje omawiany interfejs.
Poniżej przedstawiam krótki przykład jak tego używać (implementacja w DevPrototype)

public Dictionary SelectedDictionary { get; set; }
public ObservableCollection DictionariesCollection
{
    get { return _dictionariesCollection; }
    set
    {
        _dictionariesCollection = value;
        Dictionaries = new PagedCollectionView(_dictionariesCollection);
        Dictionaries.CurrentChanged += SelectedItemChanged;
        NotifyOfPropertyChange(() => DictionariesCollection);
    }
}
public ICollectionView Dictionaries
{
    get { return _dictionaries; }
    set
    {
        _dictionaries = value;
        NotifyOfPropertyChange(() => Dictionaries);
    }
}

private void SelectedItemChanged( object sender, EventArgs e )
{
     SelectedDictionary = Dictionaries.CurrentItem as Dictionary;
}
private void OnGroupCommand(object obj)
{
    Dictionaries.GroupDescriptions.Add(new PropertyGroupDescription("Description"));
}
private void OnUngroupCommand(object obj)
{
    Dictionaries.GroupDescriptions.Clear();
}
private void OnSortCommand(object obj)
{
   Dictionaries.SortDescriptions.Add(new SortDescription("Description",ListSortDirection.Ascending));
}

DelegateCommand implementuje interfejs ICommand (polecam post „Dziennik Zdrowej Diety – Wzorzec MVVM – Commanding” oraz dokłada dwie rzeczy. Pierwsza to możliwość wymuszenie ponownego sprawdzenia metody CanExecute przez metodę RaiseCanExecuteChanged(); Drugą rzeczą jest powiązanie wartości właściwości IsEnabled z wynikiem metody CanExecute. Te dwie rzeczy świetnie się uzupełniają w scenariuszach, gdzie np. mamy walidowane pola oraz przycisk „Zapisz”. Warto pamiętać, że podpinając DelegateCommand pod Button, nie mamy możliwości własnoręcznego zbindowania propercji IsEnabled. Klasa ta była także budowana dla kontrolek dziedziczących z ButtonBase. Ludzie od Prisma sami sugerują w książce, że dla innych kontrolek oraz innych zdarzeń warto przyjrzeć się Behavior’om z SDK Blenda. Głównie mają na myśli InvokeCommandAction oraz CallMethodAction. Po szczegóły na temat tych dwóch Behavior’ów odsyłam do posta „Przegląd Action (Blend SDK) w kontekście MVVM cz. 1„

Construction and Wire-Up
Dział ten opisuje starategie zarządzania View oraz ViewModel. Mamy tutaj do wybory:
- ViewModel First – najpierw inicjalizowany jest ViewModel, a następnie wewnątrz ViewModelu instancjonowana jest formatka View. Należy pamiętać by trzymać w takim ViewModelu bezparametrowy konstruktor w celu prawidłowego wyświetlania naszego View w designerze VS bądź Blend.
- View First – najpierw inicjalizowany jest View. Tworzenie instancji ViewModelu może się odbywać zarówno w kodzie XAML jak i w zdarzeniu Loaded. Po szczegóły odnośnie tej strategii odsyłam do posta „Dziennik Zdrowej Diety – Blendability MVVM”

MessageBox i PopUp
To w sumie jedyna oryginalna rzecz jaką stworzył team PRISM na potrzeby wzorca MVVM. Zestaw klas i interfejsów IInteractionRequest, InteractionRequestTrigger, Confirmation i Notification ma na celu wspomóc programistę przy tworzeniu wyskakujących okienek, okienek typu MessageBox w taki sposób by w ViewModelu nie było bezpośredniego odwołania do np. specyficznych rzeczy dostępnych tylko w Silverlight. Ułatwia to także testowanie, gdzie wywołanie tego typu komponentów odbywa się na zasadzie zdarzeń.
Prosty przykłąd

var result = interactionService.ShowMessageBox(
           "Are you sure you want to cancel this operation?",
           "Confirm",
           MessageBoxButton.OK );

if (result == MessageBoxResult.Yes)
{
CancelRequest();
}

Odnośnie interakcji naszego ViewModel’u z logiką UI odsyłam do posta „Dziennik Zdrowej Diety – Logika UI w MVVM”, gdzie przedstawiłem własną koncepcję jak nasz ViewModel może operować z logiką dostępną po stronie widoku nie będąc bezpośrednio powiązanym z tym widokiem.

Brak komentarzy:

Prześlij komentarz