Xamarin.Forms: Our (my) first very simple IValueConverter implementation
Wednesday, May 17, 2017
In this tutorial I will make very simple implementation of IValueConverter in Xamarin.Forms. Till this day I was avoiding the IValueConverter for no reason but I hope after this blog post you will also use it more frequently. The title for this blog post can be also: Very simple usage of IValueConverter in Xamarin.Forms.
Quick note: I am sure that there is a lot of great resources on the web about Xamarin.Forms and IValueConverter but my mission is to make this blog post with very simple use case in order to understand it.
In this tutorial I will make simple app that will have two labels, four buttons and user will chose between four season to answer question: "I was born in the:" and when user clicks on one of the buttons background color will be changed.
That is not something special but BackgroundColor property of StackLayout will be binding to the property that is not type of Color but instead it will be a String in our ViewModel and this is possible by using IValueConverter.
So let't get started.
Create new Xamarin.Forms app and follow these steps:
Create new folder called ViewModels and inside of ViewModel called MainPageViewModel add these properties:
using System; | |
using System.Collections.Generic; | |
using System.ComponentModel; | |
using System.Linq; | |
using System.Runtime.CompilerServices; | |
using System.Text; | |
using System.Threading.Tasks; | |
using System.Windows.Input; | |
using Xamarin.Forms; | |
namespace IValueConverter_Xamarin.Forms.ViewModels { | |
public class MainPageViewModel : INotifyPropertyChanged{ | |
private string season; | |
public string Season { | |
get { return season; } | |
set { season = value; | |
OnPropertyChanged("Season"); | |
} | |
} | |
public ICommand WinterSelected { get; private set; } | |
public ICommand SpringSelected { get; private set; } | |
public ICommand SummerSelected { get; private set; } | |
public ICommand AutumnSelected { get; private set; } | |
public MainPageViewModel() { | |
WinterSelected = new Command(SetWinter); | |
SpringSelected = new Command(SetSpring); | |
SummerSelected = new Command(SetSummer); | |
AutumnSelected = new Command(SetAutumn); | |
} | |
void SetWinter() { | |
Season = "Winter"; | |
} | |
void SetSpring() { | |
Season = "Spring"; | |
} | |
void SetSummer() { | |
Season = "Summer"; | |
} | |
void SetAutumn() { | |
Season = "Autumn"; | |
} | |
public event PropertyChangedEventHandler PropertyChanged; | |
void OnPropertyChanged(string propertyName = "") => | |
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); | |
} | |
} |
As you can see we have one string property called Season and four ICommand properties which our buttons will be binding for click event. Also we have four methods which will be called when some of the buttons are clicked.
When one of the button is clicked for example Winter button the property "Season" will be set to the value of Winter.
And the UI XAML code for this view will be this:
<?xml version="1.0" encoding="utf-8" ?> | |
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" | |
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | |
xmlns:local="clr-namespace:IValueConverter_Xamarin.Forms" | |
x:Class="IValueConverter_Xamarin.Forms.MainPage"> | |
<StackLayout HorizontalOptions="Fill" | |
VerticalOptions="Fill"> | |
<StackLayout HorizontalOptions="CenterAndExpand" | |
VerticalOptions="CenterAndExpand"> | |
<Label Text="I was born in the:" | |
FontSize="Large" | |
TextColor="Black" | |
FontAttributes="Bold" | |
HorizontalTextAlignment="Center" /> | |
<Label Text="{Binding Season}" | |
FontSize="Large" | |
TextColor="Black" | |
FontAttributes="Bold" | |
HorizontalTextAlignment="Center" /> | |
<Button Text="Winter" | |
TextColor="Black" | |
FontAttributes="Bold" | |
BackgroundColor="White" | |
Command="{Binding WinterSelected}" | |
HorizontalOptions="Fill" /> | |
<Button Text="Spring" | |
TextColor="Black" | |
FontAttributes="Bold" | |
BackgroundColor="White" | |
Command="{Binding SpringSelected}" | |
HorizontalOptions="Fill" /> | |
<Button Text="Summer" | |
TextColor="Black" | |
FontAttributes="Bold" | |
BackgroundColor="White" | |
Command="{Binding SummerSelected}" | |
HorizontalOptions="Fill" /> | |
<Button Text="Autumn" | |
TextColor="Black" | |
FontAttributes="Bold" | |
BackgroundColor="White" | |
Command="{Binding AutumnSelected}" | |
HorizontalOptions="Fill" /> | |
</StackLayout> | |
</StackLayout> | |
</ContentPage> |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Xamarin.Forms; | |
namespace IValueConverter_Xamarin.Forms { | |
public partial class MainPage : ContentPage { | |
public MainPage() { | |
InitializeComponent(); | |
BindingContext = new ViewModels.MainPageViewModel(); | |
} | |
} | |
} |
If you are no familiar with MVVM and binding in Xamarin.Forms please take a look at some of my previous blog posts:
- https://almirvuk.blogspot.ba/2017/02/xamarinforms-listview-simple-mvvm.html
- https://almirvuk.blogspot.ba/2016/12/xamarinforms-simple-mvvm-binding-example.html
For this kind of functionality we need IValueConverter, to set background color of stack layout by binding to the Season property. As you know we can not bind BackgroundColor to the String type, that does not make sense. So we can implement some logic inside of IValueConverter to get Color type based on the Season property.
- Convert .. and
- ConvertBack
- value - The value produced by the binding source.
- targetType - The type of the binding target property.
- parameter - The converter parameter to use.
- culture - The culture to use in the converter.
using System; | |
using System.Collections.Generic; | |
using System.Globalization; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Xamarin.Forms; | |
namespace IValueConverter_Xamarin.Forms.Converters { | |
public class ColorConverter : IValueConverter { | |
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { | |
if (value as string == "Winter") | |
return Color.FromHex("#2980b9"); | |
else if(value as string == "Spring") | |
return Color.FromHex("#2ecc71"); | |
else if (value as string == "Summer") | |
return Color.FromHex("#1abc9c"); | |
else if (value as string == "Autumn") | |
return Color.FromHex("#e67e22"); | |
return Color.FromHex("#000000"); | |
} | |
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { | |
throw new NotImplementedException(); | |
} | |
} | |
} |
As you can see we are using the Convert method and value that we are binding to, in this case property Season in our ViewModel we are taking and casting as string, and using if statement we are checking what is user choice.
Depending on what season user is selected, convert method will return the type of Color with some Hex value.
Our IValueConverter is ready, only thing that we need to do is to use it in the XAML.
First step is to set namespace in the ContentPage definition:
xmlns:converter="clr-namespace:IValueConverter_Xamarin.Forms.Converters" |
Using IValueConverter like this property that we are binding to will be "value" parameter inside our Convert method in ColorConverter.
Now we can use our IValueConverter at StackLayout property for BackgroundColor like this:
<StackLayout HorizontalOptions="Fill" | |
VerticalOptions="Fill" | |
BackgroundColor="{Binding Season, Converter={StaticResource colorConverter}}"> |
This is how our MainPage.xaml looks now:
<?xml version="1.0" encoding="utf-8" ?> | |
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" | |
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | |
xmlns:local="clr-namespace:IValueConverter_Xamarin.Forms" | |
x:Class="IValueConverter_Xamarin.Forms.MainPage" | |
xmlns:converter="clr-namespace:IValueConverter_Xamarin.Forms.Converters"> | |
<ContentPage.Resources> | |
<ResourceDictionary> | |
<converter:ColorConverter x:Key="colorConverter" /> | |
</ResourceDictionary> | |
</ContentPage.Resources> | |
<StackLayout HorizontalOptions="Fill" | |
VerticalOptions="Fill" | |
BackgroundColor="{Binding Season, Converter={StaticResource colorConverter}}"> | |
<StackLayout HorizontalOptions="CenterAndExpand" | |
VerticalOptions="CenterAndExpand"> | |
<Label Text="I was born in the:" | |
FontSize="Large" | |
TextColor="White" | |
FontAttributes="Bold" | |
HorizontalTextAlignment="Center" /> | |
<Label Text="{Binding Season}" | |
FontSize="Large" | |
TextColor="White" | |
FontAttributes="Bold" | |
HorizontalTextAlignment="Center" /> | |
<Button Text="Winter" | |
TextColor="Black" | |
FontAttributes="Bold" | |
BackgroundColor="White" | |
Command="{Binding WinterSelected}" | |
HorizontalOptions="Fill" /> | |
<Button Text="Spring" | |
TextColor="Black" | |
FontAttributes="Bold" | |
BackgroundColor="White" | |
Command="{Binding SpringSelected}" | |
HorizontalOptions="Fill" /> | |
<Button Text="Summer" | |
TextColor="Black" | |
FontAttributes="Bold" | |
BackgroundColor="White" | |
Command="{Binding SummerSelected}" | |
HorizontalOptions="Fill" /> | |
<Button Text="Autumn" | |
TextColor="Black" | |
FontAttributes="Bold" | |
BackgroundColor="White" | |
Command="{Binding AutumnSelected}" | |
HorizontalOptions="Fill" /> | |
</StackLayout> | |
</StackLayout> | |
</ContentPage> |
.
Full project and source code is available on the my GitHub page at this URL: https://github.com/almirvuk/IValueConverter_Xamarin.Forms
I hope this tutorial/blog post was helpful for you, and that you understand the basic and simple usage of IValueConverter, and in the future I am sure that I will use it more often because it simplifies some things.
Share it if you like it.
Best regards! Almir Vuk | https://almirvuk.blogspot.com
0 comments