Opis przygotowany na podstawie pracy magisterskiej Dawida Czaji "Programowanie wieloplatformowych aplikacji z użyciem Xamarin i MVVMCross" (UMK 2018) 1. Przygotowanie szablonu projektów Xamarin+MVVMCross częścią wspólną w postaci PCL a. Tworzymy nowy projekt typu Android App (Xamarin) z szablonem Blank App Name: Kolory.Android Solution name: Kolory b. Do rozwiązania dodajmy projekt typu Class Library (Legacy Portable) o nazwie Kolory.Core Do obsługiwanych platform dodajmy Windows Universal 10.0, a usuwamy .NET Framework 4.5.1 (niektóre wtyczki nie obsługują tej platformy) Można z tego projektu usunąć plik Class1.cs c. Do rozwiązania dodajmy projekt typu Blank App (Universal Windows) o nazwie Kolory.UWP d. We wszystkich trzech projektach instalujemy pakiet NuGet o nazwie MvvmCross.StarterPack (u mnie jest wersja 5.7.0) 2. Projekt PCL a. Instalujemy wtyczkę służącą do obsługi kolorów w poszczególnych platformach - pakiet NuGet MvvmCross.Plugin.Color (u mnie najnowsza wersja 6.6.2, ale zainstalowałem 5.7.0 ze względu na zgodność z wybranymi platformami) b. Tworzymy folder Models i umieszczamy w nim klasę KolorModel (plik KolorModel.cs) namespace Kolory.Core.Models { class KolorModel { public byte R, G, B; public KolorModel(byte r, byte g, byte b) { R = r; G = g; B = b; } public void Resetuj() { R = 0; G = 0; B = 0; } } } c. w pliku ViewModels\MainViewModel.cs usuwamy niepotrzebną własność Text, pole _text, metodę ResetText i polecenie, a następnie dodajemy własności opisujące składowe koloru oraz własność typu MvxColor z wtyczki using System.Threading.Tasks; using MvvmCross.Core.ViewModels; using MvvmCross.Platform.UI; namespace Kolory.Core.ViewModels { public class MainViewModel : MvxViewModel { private Models.KolorModel model = new Models.KolorModel(0, 0, 0); public MainViewModel() { } public override Task Initialize() { //TODO: Add starting logic here return base.Initialize(); } public byte R { get { return model.R; } set { model.R = value; RaisePropertyChanged(nameof(R)); RaisePropertyChanged(nameof(Kolor)); } } public byte G { get { return model.G; } set { model.G = value; RaisePropertyChanged(nameof(G)); RaisePropertyChanged(nameof(Kolor)); } } public byte B { get { return model.B; } set { model.B = value; RaisePropertyChanged(nameof(B)); RaisePropertyChanged(nameof(Kolor)); } } public MvxColor Kolor { get { return new MvxColor(R, G, B); } } } } Klasa MvxViewModel implementuje interfejs INotifyPropertyChanges - stąd wywołania RaisePropertyChanged, która zgłasz zdarzenie PropertyChanged. d. Dodajemy metodę resetującą kolor i polecenie, które ją wywołuje public void Resetuj() { model.Resetuj(); RaisePropertyChanged(nameof(R)); RaisePropertyChanged(nameof(G)); RaisePropertyChanged(nameof(B)); RaisePropertyChanged(nameof(Kolor)); } public IMvxCommand ResetujCommand { get { return new MvxCommand(Resetuj); } } //public IMvxCommand ResetujCommand => new MvxCommand(Resetuj); e. Przechodzimy do pliku App.cs i zmieniamy wywołanie przestarzałej metody RegisterAppStart na RegisterNavigationServiceAppStart using MvvmCross.Platform.IoC; namespace Kolory.Core { public class App : MvvmCross.Core.ViewModels.MvxApplication { public override void Initialize() { CreatableTypes() .EndingWith("Service") .AsInterfaces() .RegisterAsLazySingleton(); //RegisterAppStart(); RegisterNavigationServiceAppStart(); } } } 3. Aplikacja-widok dla Xamarin-Android a. W pliku MainActivity.cs zmieniamy klasę bazową klasy MainActivity na MvxActivity i nazwę klasy z MainActivity na MainView Uwaga! Nazwa klasy jest ważna - wiązanie z modelem widoku na podstawie nazwy MainView -> MainViewModel using Android.App; using Android.OS; using MvvmCross.Droid.Views; namespace Kolory.Android { [Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)] public class MainView : MvxActivity { protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // Set our view from the "main" layout resource SetContentView(Resource.Layout.activity_main); } } } b. Dodajemy odwołanie do projektu Kolory.Core c. Tworzymy klasę Setup w pliku Setup.cs (powinna była powstać automatycznie po instalacji MvvmCross.StarterPack) using Android.Content; using MvvmCross.Core.ViewModels; using MvvmCross.Droid.Platform; using MvvmCross.Platform.Platform; namespace Kolory.Android { public class Setup : MvxAndroidSetup { public Setup(Context applicationContext) :base(applicationContext) { } protected override IMvxApplication CreateApp() { return new Core.App(); } protected override IMvxTrace CreateDebugTrace() { return new MvxDebugTrace(); } } } d. Zmieniamy plik widoku Resource\layout\activity_main.axml