Universal App Tutorials Part 11 : Value Converters

One of the rules of using MVVM is that your model shouldn’t need to know anything about the UI Layer, and your View should be decoupled from the Model via the ViewModel.  It can often be necessary to have some form of conversion between what our Model understands and what the View would understand.  A common example would be converting a boolean flag to a Visibility State, this is where Value Converters come in.

Outcome

We’ll follow a slightly more domain specific example in this case, converting the TranslationDirection Enumeration Property to a Visibility State for our Morse Input User Control.

Implementation

Converter

Start by creating a folder for our Converters to reside.  We want the Converters to be in the UI Layer, so create a folder under the MorseCoder Project called Converters.

Converters Folder
Converters Folder under MorseCoder Project

Now create a new Class in the newly created Converters folder, called TranslationDirectionToMorseInputVisibilityConverter.  We want this to inherit from and implement IValueConverter in the Windows.UI.Xaml.Data namespace.

 using System;
 using Windows.UI.Xaml.Data;

namespace MorseCoder.Converters
 {
 public class TranslationDirectionToMorseInputVisibilityConverter : IValueConverter
 {
 public object Convert(object value, Type targetType, object parameter, string language)
 {
 throw new NotImplementedException();
 }

public object ConvertBack(object value, Type targetType, object parameter, string language)
 {
 throw new NotImplementedException();
 }
 }
 }
 

This will take ultimately take a TranslationDirection Direction Property from the MainViewModel as input, and we want to return a Visibility State.  For now at least we are only interested in one way conversion so we’ll leave the ConvertBack unimplemented.

It’s normally a good practice to assert that our input type is correct, so let’s do that :

 public object Convert(object value, Type targetType, object parameter, string language)
 {
 if (value is TranslationDirection)
 {
 return Visibility.Visible;
 }
 return new InvalidCastException("Input value not of type TranslationDirection");
 }
 

You will notice that we’re checking the value type is what we are expecting it to be, if not it will drop out and throw an Exception.  We should now be in a position to return something meaningful from the Converter.

If the Direction is AlphabetToMorse we do not want to display the MorseInput, if it it is MorseToAlphabet, we do :

 public object Convert(object value, Type targetType, object parameter, string language)
 {
 if (value is TranslationDirection)
 {
 switch ((TranslationDirection)value)
 {
 case TranslationDirection.AlphabetToMorse:
 return Visibility.Collapsed;
 case TranslationDirection.MorseToAlphabet:
 return Visibility.Visible;
 default:
 return Visibility.Visible;
 }
 }
 return new InvalidCastException("Input value not of type TranslationDirection");
 }
 

ViewModel

We now need to wire up the _direction private field as a Public PropertyChange aware Property on the ViewModel to allow the TranslationDirection to be bound in the View :

 public TranslationDirection Direction
 {
 get
 {
 return _direction;
 }
 set
 {
 Set(() => Direction, ref _direction, value);
 }
 }
 

View

Now we need to declare our Converter as a Resource available locally to the MainPage.  Bring in the reference by adding :

 xmlns:converters="using:MorseCoder.Converters"
 

to the Page Declaration.  We can now add our new Converter as a Resource on our Page :

 <Page.Resources>
 <converters:TranslationDirectionToMorseInputVisibilityConverter x:Key="TranslationDirectionToMorseInputVisibilityConverter"/>
 </Page.Resources>
 

And finally we can refer to it in the Definition of the MorseInput User Control on the View :

 <UserControls:MorseInput Visibility="{Binding Direction, Converter={StaticResource TranslationDirectionToMorseInputVisibilityConverter}}" ... />
 

Note the Binding to Direction on our ViewModel, and the usage of the Converter we created  via the Static Resource on the page to provide the conversion from the Domain Specific Enumeration to the Xaml Visibility Type.

We can’t yet control the translation direction from the UI but it can be hard coded in the ViewModel for testing, we now have :

MorseToAlphabetMorseInputVisible.png
Morse to Alphabet Input Visible

…and…

AlphabetToMorseMorseInputCollapsed.png
Alphabet to Morse Input Collapsed

Summary

Where are we?

  • We created our first Converter to map between the Model and Views;
  • Registered the Converter as a Page Resource;
  • Used the new Converter on the View to show and hide the Morse Input based on the state of the ViewModel.

Where are we heading?

We’ll look at:

  • adding some more functionality to the app to swap the translation direction;
  • adding some functionality to our clean slate About Page;
  • methods of serialising POCOs to Application Settings.

One thought on “Universal App Tutorials Part 11 : Value Converters”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s