Fix common binding errors with MVVM Light on Xamarin
There isn’t much documentation available for MVVM Light
when it comes to Xamarin.Android and Xamarin.iOS. There are several overloads for the
SetBinding method and using the wrong overload causes
TargetException like this one
. It’s also possible that your bindings don’t update anymore after you set one binding using an incorrect syntax.
You can only bind on properties, not on fields. You can use the new C# 6 syntax if you like (
public TextView TextView => ...). They don’t always have to be
public but it sure helps making them
public either way. The easiest way to create a new view property on Android is with the
mvvmdroidelement snippet provided by this extension
You should put your bindings in your views and make sure to respect the lifecycle of the platform you’re using. Also, always keep a reference to your binding so it doesn’t get garbage collected. I usually Store a list with all my bindings in my view.
First create your layout in the
OnCreate method, create and store the bindings and activate/update the view model if necessary. Call
Detach() on every binding in the
The layout can be set up in
OnCreateView. Use the
OnViewCreated method to set and store the bindings and activate/update the view model if necessary. Call
Detach() on every binding in the
Initialize everything in the
ViewDidLoad method. Then use the
ViewWillAppear method to set and store the bindings. In some rare cases it helps calling
ViewDidAppear. Bindings should be detached using
Detach() on the binding in
ViewWillDisappear. You can use
DidReceiveMemoryWarning to clean up or dispose some references.
Static view models
To avoid the mentioned
TargetException, I’d recommend setting up a static view model locator as Laurent Bugnion explained
and using the view models on that locator. Injecting a view model in your view to bind on, usually causes the
TargetException, so try to use the view models defined in the locator.
Is the source of your binding a property in your view?
Then use this one:
1this.SetBinding(() => Path.To.Property.On.Your.View, App.Locator.MyViewModel, () => App.Locator.MyViewModel.Path.To.Property.On.Your.ViewModel, BindingMode.OneWay)
Is the source of your binding a property in your view model?
Then use the following overload:
1App.Locator.MyViewModel.SetBinding(() => App.Locator.MyViewModel.Path.To.Property.On.Your.ViewModel, this, () => Path.To.Property.On.Your.View, BindingMode.OneWay);
1this.SetBinding(() => Path.To.Property.On.Your.View, App.Locator.MyViewModel, () => App.Locator.MyViewModel.Path.To.Property.On.Your.ViewModel, BindingMode.TwoWay);
Binding to a target type different from the source type
1App.Locator.MyViewModel.SetBinding(() => App.Locator.MyViewModel.Path.To.Property.On.Your.ViewModel, this, () => Path.To.Property.On.Your.View, BindingMode.OneWay).ConvertSourceToTarget(ConversionMethod);
You can also use a lambda, but that’s harder to debug.
Just binding to a source and updating the view yourself
1App.Locator.MyViewModel.SetBinding(() => App.Locator.MyViewModel.Path.To.Property.On.Your.ViewModel).WhenSourceChanges(MyUpdateMethod);
I guess this should cover all cases. I wrote this post using MVVM Light v5.2, but v5.3 or v6 is in the works (probably to be released at Xamarin Evolve 2016), so your mileage may vary with these newer versions.
You might also like
Dependency injection with Autofac and MVVM Light in Xamarin
You gotta have MVVM A developer and his tools are inseparable. We all like SOLID and every (.NET) developer has his or her favourite dependency injection tool. There is a lot to choose from. I like Autofac because of the way it handles modules, the lifetime of a type and how it registers types.
Queue for MessageDialog in Windows RT
When I write Windows Store applications, I use MessageDialog a lot. It’s the easiest way to show a quick informative pop-up message or a question to the user. However, when you tend to use this quite often, you’ll probably run into a problem. The Windows Runtime framework doesn’t allow you to stack MessageDialogs, queue them etc.