Implementacja MVVMLight w Xamarin.Forms

Implementacja MVVMLight w Xamarin.Forms

Drogi czytelniku domniemam, że posiadasz już podstawową wiedzę na temat wzorców projektowych oraz wstrzykiwania zależności w aplikacji. Nie będzie tu wpisu dlaczego powinieneś wybrać MVVM zamiast MVC,  lub czemu moje rozwiązanie jest lepsze od innych, prawdopodobnie istnieje wiele lepszych więc zachęcam Cię do przeszukania zasobów internetu i porównania kilku innych rozwiązań zanim zastosujesz to co tutaj przedstawię. Wszystkie przykłady kodu pochodzą z mojej autorskiej aplikacji i zostały w niej użyte. Enjoy 🙂

Poniższe przykłady bazują na bibliotece MVVMLight.

Pierwszym krokiem implementacji MVVMLight w aplikacji Xamarin, jest deklaracja ViewModelLocator‚a w nadrzędnej klasie App.cs. Klasa ViewModelLocator jest dostarczona przez autorów biblioteki, w której powinna odbywać się deklaracja wszystkich ViewModel’i (w dalszej części będę używał skrótu VM), dzięki czemu programista ma dostęp do instancji VM w każdej części swojej aplikacji. Standardowo po instalacji biblioteki MVVMLight, ViewModelLocator znajduje się w katalogu ViewModel.

Moja propozycja budowy struktury aplikacji:

 

 

 

 

W poniższym wycinku deklaracja locatora odbywa się w linii 7 oraz 8.

 

Kolejnym krokiem, jest dodanie nowego VM. Na potrzeby tego artykułu będzie to BaseViewModel. W moim przypadku jest to nadrzędny VM po którym dziedziczą wszystkie inne ViewModele. Umieściłem w nim funkcje które moim zdaniem mogłyby się powielić w innych ViewModelach (zasada DRY [Don’t repeat yourself]), takie jak sprawdzenie czy użytkownik dalej jest zalogowany, pobieranie i zapisywanie uprawnień przypisanych do konta czy bardzo ważna z mojego punktu widzenia implementacja funkcji OnPropertyChanged, która jest wywoływana za każdym razem gdy zmieni się właściwość po stronie kodu i chcemy ją odświeżyć w widoku.

 

Po stworzeniu pierwszego ViewModel’u, należy go zarejestrować w kontenerze IOC (SimpleIOC), w tym momencie powinieneś posiadać podstawową wiedzę na temat wstrzykiwania zależności, o której wspominałem na początku artykułu. Kontener IOC został dostarczony przez autorów biblioteki MVVMLight. Sama rejestracja obiektu jest dość prostą sprawą, możesz zobaczyć to w 9 linii poniższego przykładu. Po rejestracji obiektu, należy dodać możliwość odwołania się do owego obiektu. Jest to zwyczajny getter z wywołaniem metody GetInstance ServiceLocator’a z nazwą obiektu, linia 12-15.

 

Po zadeklarowaniu VM w ViewModelLocator, należy dodać nowy widok w katalogu Views, w którym zostanie wyświetlony tekst zadeklarowany w BaseViewModel. W przypadku tego artykułu widok będzie nazywał się BasePage. Dobrą zasadą jest nazywać podobnie ViewModele oraz Widoki, przykładowo:

ViewModel: BaseViewModel,  Widok: BasePage

ViewModel: LoginViewModel, Widok: LoginPage

Po dodaniu widoku, powinieneś otrzymać podobny plik XAML jak w przykładzie niżej. Jest to „prawie” pusty widok, jego jedynym zadaniem jest wyświetlenie napisu powitalnego zadeklarowanego, z wcześniej zadeklarowanego ViewModelu.

 

Przejdźmy teraz do warstwy kodu widoku (BasePage.xaml.cs), w której następuje powiązanie widoku z ViewModelem. Wiązanie odbywa się poprzez przypisanie obiektu wcześniej zadeklarowanego ViewModelu do właściwości BindingContext w tym przykładzie jest to linia 6.

Po wykonaniu wszystkich czynności które opisałem, zostało jedynie ustawić BasePage jako strony startowej aplikacji. Robi się to przez przypisanie obiektu BasePage do właściwości MainPage w  klasie App.cs, finalna wersja pliku App.cs:

Po przebudowaniu oraz deploy’u projektu, na emulatorze powinna ukazać się strona startowa z tekstem powitalnym „Hello world”. Mam nadzieję, że rozjaśniłem Ci trochę proces implementacji MVVMLight w aplikacjach Xamarin.Forms. Jeżeli masz jakieś uwagi, pytania lub propozycje lepszego rozwiązania, napisz koniecznie o tym w komentarzu.

W kolejnych artykule planuję opisać działanie Hamburger menu czyli MasterDetailPage w Xamarin.Forms.

 

  • Hej. Polecam zamiast deklarować w BaseViewModel

    protected void OnPropertyChanged(string name)
    {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }

    użyć wbudowanej metody w MVVM Light + C#6, wówczas w docelowym modelu wystarczy napisać:

    RaisePropertyChanged(nameof(SearchText));

    • Adrian Szeń

      Cześć,

      Dzięki za wskazówkę, musiałem przeoczyć RaisePropertyChanged.

  • Pingback: How to implement Hamburger menu in Xamarin.Forms - Working with Master Detail Page - Adrian Szeń()

  • Tomasz Janczewski

    Hej. To ja od siebie dodam też dwie małe porady.
    Powiadamianie o zmianach w property powinno następować jeśli zachodzi zmiana czyli nie powinno być OnPropertyChanged wywoływane po ustawianiu gdzieś w kodzie property tylko w samym setterze po ustawieniu wartości (tutaj najlepiej używać tzw. fullpropów, czyli dodać private string welcomeText i z niego skorzystać).
    Po drugie wrzucanie swojego kodu do App.cs jest raczej niezbyt ładne, polecam zapoznać się z tym czym jest bootstraper w takich aplikacjach i dodać sobie po prostu klasę, która będzie takim bootstrapperem a w App.cs czy App.xaml.cs (szczerze mówiac nie wiem jak to wygląda w Xamarin) sobie utworzyć obiekt i wywołać jakąś metodę inicjującą.
    Pozdrawiam i będę obserwował, bo z Lighta i Xamarina nie dane mi było jeszcze korzystać 😉

Comments are closed.