When using Xamarin.Forms and the MVVM pattern within your app, at some point you are going to run into a problem. The problem is that you want to bind to a value that is not the right type. For example, you want to bind some enum value to the text color. This can easily be done by implementing the IValueConverter interface to create a value converter.
What are value converters?
The concepts of value converters is pretty straight forward. You create a class that implements the IValueConverter which makes you implement the Convert and ConvertBack methods. With these methods you can take any kind of object and write your own logic to transform it into any other object. To stick with our example above, you can take in a enum and write your own switch statement to decide on a color for a label. How this works exactly we will see in a moment. Also, this concept isn’t specific to Xamarin, you will also find it in other applications that can leverage the MVVM pattern.
Why do we need value converters?
When you are implementing MVVM and more specifically data-binding, you are eventually will run into the problem that you want to use a custom type to influence some UI element. You can get around this in several ways, but the most elegant one will be to leverage the IValueConverter interface.
How do I use value converters?
Let’s have a look at some code. First I will give you a scenario that lets you see the problem. Imagine we have a page with a ListView. The ListView shows us a list (doh) of custom, complex types and depending on one of the properties of that object, you want to give the text a certain color. A screenshot of our initial solution can be seen below.
Writing the IValueConverter
In this solution we want to make clear to the user which game is for which platform. The way we are going to do this is to give each game a certain color, based on the platform enum. The first thing we need to do is create the actual value converter. Below you see the empty implementation I have created.
Note how I have implemented the IValueConverter interface. This interface consists of two methods: Convert and ConvertBack. As you could’ve guessed, this is for the conversion back and forth. It isn’t uncommon that the ConvertBack is not implemented. For instance, the example we will build here, will just convert the enum to a color. The color will never be converted back to the enum. Although we could do this, there is no point.
In the code below I have implemented the Convert method.
Because the incoming value and return type are both object, you will have to do some casting and/or parsing with the accompanying error handling. So, the first thing I try to do is figure out if it is the enum we’re after and if so, what it’s value is. In any case where I cannot determine the value, I just return to the default black color. Like I have mentioned, the ConvertBack is not implemented as per the IValueConverter right now. But if there was a use-case for it, just implement an inverse of the Convert method implementation.
Implementing the UI
Finally, to tie it to the UI we will declare the converter on the page and use it in our binding. Any bindable property can make use of a value converter.
Right above here you see the page I have created to show the games. The real magic is happening in the TextCell. You see that I bind the TextColor property to the GamePlatform, which is the enum. Normally, this will just take the object call the ToString method and output that. But now, the value of the GamePlatform will be used as input parameter for the Convert method. Besides specifying the binding, you will also state a Converter property. The way I have implemented it, is by a using it as a static resource. You can declare a resource at either page or application level, or somewhere in between.
This means, if you write a converter that is used in multiple parts of your application you can easily reuse it.
When we run the app again with our converter in place, the output will now look like this:
Of course, this is just a simple example, but I actually use it in this form for the BudgetGaming app. You can see a screenshot below. Per game is shown for which platform it is and it shows a little tag in the right color. Solving it this way with a value converter prevents you from implementing properties that are just for UI elements. This is not something you should want in a MVVM app.
You can find the code for the sample project in this post on my GitHub.
Making your life easier..
After finishing this post, I quickly got a tip from Matthew himself, reminding me that MFractor can do this for you on Visual Studio for Mac and Xamarin Studio.
Using this, saves you a lot of manual work and if you look closely, you also see that you can make the converters a bit more type-safe.