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 ObservableCollectionDictionariesCollection { 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