×
Namespaces

Variants
Actions

MVVM binding enum to listview with translations

From Nokia Developer Wiki
Jump to: navigation, search

This article explains how to use an enum als source for a listview through MVVM binding even with language translation

SignpostIcon XAML 40.png
Article Metadata
Tested with
SDK: Windows Phone 8.1 SDK
Devices(s): Nokia Lumia 925
Article
Created: Depechie (08 Jul 2014)
Last edited: Depechie (08 Jul 2014)

Contents

Introduction

Sometimes we want the user to make a simple selection based upon a list of items. Often this list of items represents an enum in our code, but like you know, enums are not that user friendly when presented in an app. So let's explore a solution on how we can fix this!

Implementation

In this article we'll discuss a solution using the Windows Phone 8.1 xaml store app SDK, but it's of course also valid in a Windows 8.1 xaml store app! Most of it will also be portable to a Windows Phone 8 silverlight app, but take not that the ListView control isn't available there, so switch to a LongListSelector! Also good to know, is that we are using MVVM Light as our preferred MVVM toolkit.

First we need an enum that can be used as source for our list. We are going to present some gender options to the user for him to make a selection. The enum looks like this:

public enum Gender
{
Unknown,
Male,
Female
}

Next we need to define our page layout, so create a new Windows Phone 8.1 xaml store app and in the MainPage.xaml add following controls

<StackPanel Grid.Row="0"
Orientation="Horizontal">
<TextBlock Text="selected value:"
Margin="0,0,6,12"
Style="{StaticResource BodyTextBlockStyle}"/>
 
<TextBlock x:Name="SelectedValue"
Text="{Binding SelectedValue}"
Style="{StaticResource BodyTextBlockStyle}"/>
</StackPanel>
 
<ListView x:Name="EnumListView"
Grid.Row="1"
ItemsSource="{Binding SelectionType, Mode=TwoWay, Converter={StaticResource EnumTypeToListConverter}}"
SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding }" FontSize="30" Margin="0,0,0,6" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

You’ll notice that the ItemSource is not binding to some collection! It’s binding to the actual type of the enum and through the use of a converter we will return the needed display values. More on this converter later in the article. We are also showing the selected value inside a textblock as reference, to show you that we are really getting an enum value! The binding properties are defined in the MainViewModel like this:

private Type _selectionType;
public Type SelectionType
{
get { return _selectionType; }
set
{
if (_selectionType == value)
return;
 
_selectionType = value;
RaisePropertyChanged();
}
}
 
private int _selectedIndex;
public int SelectedIndex
{
get { return _selectedIndex; }
set
{
if (_selectedIndex == value)
return;
 
_selectedIndex = value;
this.SelectedValue = Enum.GetValues(this.SelectionType).GetValue(SelectedIndex).ToString();
RaisePropertyChanged();
}
}

The actual enum will be returned through the SelectionType property and the return type is System.Type. Also when the ListView has a selected index change, you’ll see that we’re using that current selected index to determine what enum value was actually chosen and we set that to the SelectedValue property. Only thing missing now is initializing the SelectionType property with the actual Gender enum we want to display! For our demo we do this in the constructor of the MainViewModel.

public MainViewModel()
{
this.SelectionType = typeof (Enums.Gender);
_selectedIndex = -1;
}

With this the ListView still can’t do anything with the given enum type, so we need to use a converter to return presentable display values! The convert part of our EnumTypeToListConverter looks like this.

public object Convert(object value, Type targetType, object parameter, string language)
{
if (value == null)
return null;
 
var enumType = value as Type;
if (enumType == null || !enumType.GetTypeInfo().IsEnum)
return null;
 
var values = Enum.GetValues((Type)value).Cast<Enum>();
 
return values.Select(item => resourceLoader.GetString(string.Format("{0}_{1}", enumType.Name, item))).ToList();
}

We get the enum type as value parameter and use this to get all values of the given type through use of the general Enum.GetValues method. With this we have all values that the given enum has, but these still aren’t usable to present inside the app! To fix this, we use a resource loader to get a nice display value for each enum value from the current loaded language resource. Finally we convert this to a list and return it to the ListView.

For this all to work you’ll need to add some resource files for each language you are going to support and inside each resource file you’ll need to add a display value for each enum value.

In our case we are using following format [enum type name]_[enum value]. So for our gender enum this gives following resource entries. For adding these resources, take a look at this good explanation here...

MVVM Enum binding resources.png

Video demo

The media player is loading...

Download

A full working example is available as a repository on my GitHub here...

This page was last modified on 8 July 2014, at 11:50.
338 page views in the last 30 days.
×