Daniel Hindrikes
Developer and architect with focus on mobile- and cloud solutions!
Developer and architect with focus on mobile- and cloud solutions!
I think MVVM is a good design pattern to separate UI and business logic. MvvmLight is one of the most popular frameworks for MVVM. In this blog post I will show how you can use MvvmLight when we're building a iOS app with Xamarin.
The fist step is to create a view model. I always have my view models in a PCL (Portable Class Library) so I can share the view models with other platforms, Android and Windows for example.
When I have created a new project I will install MvvmLight to it. The easiest way to do that is to install the NuGet package for MvvmLight. The package should be added to both the PCL project and the iOS project.
Install-package MvvmLightLibs
When we are working with MVVM all ViewModels need to implement the INotifyPropertyChanged interface. INotifyPropertyChanged has one event handler, PropertyChanged that we have to implement. When using MvvmLight this is done in a base class called ViewModelBase.
In my example the viewmodel
public class MainViewModel : ViewModelBase
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
RaisePropertyChanged("Name");
}
}
public RelayCommand Send
{
get
{
return new RelayCommand(() =>
{
var nav = ServiceLocator.Current.GetInstance();
nav.NavigateTo(Views.Hello.ToString(), Name);
});
}
}
}
MvvmLight has a INavigationService interface that uses for navigation and each platform will have their own implementation. On iOS you need to create a NavigationService and configure it in the AppDelegate class.
var nav = new NavigationService();
nav.Initialize((UINavigationController)Window.RootViewController);
nav.Configure(Views.Main.ToString(), "MainView");
nav.Configure(Views.Hello.ToString(), "HelloViewController");
In my example I using Autofac for IoC, we can also use the IoC container that is in the MvvmLight package. When we have created the NavigationService we had to register it in the IoC container as a INavigationService.
var builder = new ContainerBuilder();
builder.RegisterInstance(nav);
builder.RegisterType();
builder.RegisterType();
var container = builder.Build();
var serviceLocator = new AutofacServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => serviceLocator);
If you're using storyboards you have to use the Configure(string key, string storyboardId) method. The key is just a key that we set to the view, we will use that key when we will navigate to the view. (See the code fore the ViewModel above. StoryboardId is a property that we're setting in the storyboard designer.
When using MVVM we want to use data bindings. In iOS we have to create the bindnings in code. MvvmLight will help us with that. In the class for the UIViewController we hade to add a using to the MvvmLight helpers.
using GalaSoft.MvvmLight.Helpers;
The MvvmLight helper namespace will contains the extension methods SetBinding and SetCommand.
When binding to a UITextField we can set which event who will trigger an update of the our ViewModel with the method UpdateSourceTrigger. WhenSourceChange is used to set which property in the ViewModel who will be updated.
The SetCommand method's first argument will be which event that will execute the command.
public override void ViewDidLoad()
{
base.ViewDidLoad();
//Creates a binding to a UILabel
this.SetBinding(() => ViewModel.Name, () => MyLabel.Text);
//Creates a binding to a UITextField
this.SetBinding(() => Name.Text).
UpdateSourceTrigger("EditingChanged").
WhenSourceChanges(() => ViewModel.Name = MyTextField.Text);
//Binding a command to the Button.
MyButton.SetCommand("TouchUpInside", ViewModel.Send);
}
The complete code for this sample is on GitHub, https://github.com/dhindrik/XamarinMvvmLightSample