Getting Started With Xamarin Forms MVVM Light

Introduction

Xamarin.Forms is a cross-platform UI toolkit that allows developers to easily create native user interface layouts that can be shared across Android, iOS, and Windows phones. This a great benefit for .NET(C#) Devs, mainly for Windows Phone and Store App Developers. Let's see some differences between the Xamarin.Native and Xamarin.Forms approach.


Xamarin

In Xamarin, previously we used to share only the code part with preprocessor directives targeting independent platforms like the following:

#if __IOS__  
// iOS-specific code  
#endif  
#if __ANDROID__  
// Android-specific code  
#endif  
#if Windows_App  
var path = filename;  
#else 

UI is Independent of each platform with Xamarin.Forms we can use one code one UI Across all Platforms(UI-Xaml/C#) Codebehind (C#). You can choose XAML or C# For UI. In my view, xaml is easier to go with. The sad thing is there is no designer view for Xamarin forms so every time you have to debug. So let's create our first project. In this project, we are using MVVM Light to achieve cross-platform functionality.

Make sure you have Visual Studio 2015 Installed with the latest update of Xamarin.


Blank app


After creating Project >Right Click Solution>Manage Nuget Packages>search for Xamarin Forms:


Manage Nuget Packages


Make sure you have installed Latest Xamarin Forms and Select Entire Project(Right) >Install. This will update your entire project to the latest Xamarin Forms Version. And after that Install MVVM Light.


MVVM Light


Select Entire Project and Install.

After this Go to Updates Tab in the same window. Update any Packages if Needed.

Remove Views And ViewModel Folder in All Three Platforms Except your(Portable) Project.

Now Go to your PCL Project(Top).


App.cs


Open App.cs Page.

Remove all code in App Constructor.

Write it like this:

public class App: Application  
{  
    public App()  
    {  
        MainPage = new NavigationPage(GetMainPage());  
    }  
    private static ViewModelLocator _locator;  
    public static ViewModelLocator Locator  
    {  
        get  
        {  
            return _locator ? ? (_locator = new ViewModelLocator());  
        }  
    }  
    public static Page GetMainPage()  
    {  
        return new MainPage();  
    }  
    protected override void OnStart()  
    {  
        // Handle when your app starts  
    }  
    protected override void OnSleep()  
    {  
        // Handle when your app sleeps  
    }  
    protected override void OnResume()  
    {  
        // Handle when your app resumes  
    }  
}  

By Default You will have ViewModel Folder With One View Models and One ViewModle Locator.

Now Right Click PCL Project And Add New Folder Called "Views". To that Views Folder add Again add Xaml Page.

Xaml Page


Rename it To MainPage. The name you're adding should be identical to your Viewmodel. What MvvmCross will do is, if your ViewModel is "MainViewModel" then it tries to Find A Page MainPage>means it Removes ViewModel and Replace Page and Search For That Page.

So If your ViewModel is FirstViewModel Than your Page name Should Be First Page Vise Versa.

Now Your Go To ViewModelLocator. Here you can Specify Your Default ViewModel which you want to start the Project.

public class ViewModelLocator  
{  
    /// <summary>  
    /// Initializes a new instance of the ViewModelLocator class.  
    /// </summary>  
    public ViewModelLocator()  
    {  
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);  
        ////if (ViewModelBase.IsInDesignModeStatic)  
        ////{  
        //// // Create design time view services and models  
        //// SimpleIoc.Default.Register<IDataService, DesignDataService>();  
        ////}  
        ////else  
        ////{  
        //// // Create run time view services and models  
        //// SimpleIoc.Default.Register<IDataService, DataService>();  
        ////}  
        SimpleIoc.Default.Register < MainViewModel > ();  
    }  
    public MainViewModel Main  
    {  
        get  
        {  
            return ServiceLocator.Current.GetInstance < MainViewModel > ();  
        }  
    }  
    public static void Cleanup()  
    {  
        // TODO Clear the ViewModels  
    }  
}  

Suppose if you want to start with BaseVieModel. Create a BaseViewModel class. Make sure it inherits the public class BaseVieModel: ViewModelBase.

Now in ViewModelLocator Replace MainViewModel With "BaseVieModel". So that Your Page Name Should Be "BasePage.Xaml".

Now let's get back.  So for now we have MainViewModel, ViewModelLocator registered with MainViewModel as a startup ViewModel.

So, by default your ViewModel implants INotifyProperty changed, so it makes sure when there is a change in your collection or properties it notifies the UI.


Namespace

Now to our View MainPage.Xaml just add the following code:

<?xml version="1.0" encoding="utf-8" ?>  
<ContentPage  
    xmlns="http://xamarin.com/schemas/2014/forms"  
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"  
      x:Class="XamarinMVVMLight.Views.MainPage">  
    <Button Text="{Binding ClickCountFormatted}"  
      Command="{Binding IncrementCommand}"  
      VerticalOptions="Center" />  
</ContentPage>  

Now go to MainViewModel

Add the following code:

public class MainViewModel: ViewModelBase  
{  
    public  
    const string ClickCountPropertyName = "ClickCount";  
    private int _clickCount;  
    /// <summary>  
    /// Initializes a new instance of the MainViewModel class.  
    /// </summary>  
    public MainViewModel()  
    {}  
    public int ClickCount  
    {  
        get  
        {  
            return _clickCount;  
        }  
        set  
        {  
            if (Set(() => ClickCount, ref _clickCount, value))  
            {  
                RaisePropertyChanged(() => ClickCountFormatted);  
            }  
        }  
    }  
    public string ClickCountFormatted  
    {  
        get  
        {  
            return string.Format("The button was clicked {0} time(s)", ClickCount);  
        }  
    }  
    private RelayCommand _incrementCommand;  
    /// <summary>  
    /// Gets the IncrementCommand.  
    /// </summary>  
    public RelayCommand IncrementCommand  
    {  
        get  
        {  
            return _incrementCommand ? ? (_incrementCommand = new RelayCommand(  
                () =>  
                {  
                    ClickCount++;  
                }));  
        }  
    }  
}  

So, whenever you tap on the button it will call IncrementCommand and increase the count. As our viewModel Implements INotifyProperty Changed Interface, it will bind the UI with Incremented Count Value.

Now go to Android Project, then MainActivity.cs page, and make sure the following code is there which calls PCL project at startup and respectively in all platforms.

protected override void OnCreate(Bundle bundle)  
{  
    base.OnCreate(bundle);  
    global::Xamarin.Forms.Forms.Init(this, bundle);  
    LoadApplication(new App());  
}  

 

IOS - AppDelegate.Cs

public override bool FinishedLaunching(UIApplication app, NSDictionary options)  
{  
    global::Xamarin.Forms.Forms.Init();  
    LoadApplication(new App());  
    return base.FinishedLaunching(app, options);  
}  

WindowsPhone - MainPage.Xaml.Cs Page

public MainPage()  
{  
    this.InitializeComponent();  
    LoadApplication(new App());  
}  


If you want to add Windows Phone 8.1 Or Windows 8.1 or UWP App Remove the Current windows project and go to PCL project, Properties, then change the Target Platform:

Click Change


And then add the new Windows 8.1/Windows Phone 8.1/UWP project to the solution and reference of PCL Project as well as Xamarin Forms Nuget.

Now select your own project as a startup and run. Now we successfully created our first Xamarin Forms Project. Please comment below if you have any questions.

Read more articles on Xamarin:

 


Similar Articles