Creating Converters in MvvmCross

MvvmCross is a MVVM framework for XAML platforms, similar to Caliburn Micro and MvvmLight. Unlike its competition it very much focuses on portability and code reuse across all supported XAML platforms (WPF, Windows Phone and Windows Store), and the Xamarin platforms as well (Xamarin.iOS, Xamarin.Android and Xamarin.Mac). Therefore it has its own approach to creating converters, allowing them to be implemented in a portable class library and reused on all supported platforms.

The main reason preventing that even on the Microsoft platforms, are different native IValueConverter interfaces for each supported platform, making it unavailable in portable class libraries. MvvmCross resolves this issue by introducing its own converter interface IMvxValueConverter, as well as a strongly typed generic abstract base class MvxValueConverter<TFrom, TTo>. By implementing the former or deriving from the latter, it is possible to create a portable converter which can be used on any platform:

public class OnOffConverter : MvxValueConverter<bool, string>
{
    protected override string Convert(bool value, 
        Type targetType, object parameter, CultureInfo culture)
    {
        return value ? "On" : "Off";
    }
}

Although such converters can only be bound directly using MvvmCross's Tibet binding attached properties, there are native wrappers available for each supported platform, allowing them to be used with traditional XAML binding with almost no additional code:

public class NativeOnOffConverter : MvxNativeValueConverter<OnOffConverter>
{ }

Since MvvmCross v3.1 portable converter's public properties can be exposed on native converter wrappers, as well:

public class BoolToTextConverter : MvxValueConverter<bool, string>
{
    public string TrueValue { get; set; }
    public string FalseValue { get; set; }

    protected override string Convert(bool value, 
        Type targetType, object parameter, CultureInfo culture)
    {
        return value ? TrueValue : FalseValue;
    }
}

public class NativeBoolToTextConverter : 
    MvxNativeValueConverter<BoolToTextConverter>
{
    public string TrueValue
    {
        get { return Wrapped.TrueValue; }
        set { Wrapped.TrueValue = value; }
    }

    public string FalseValue
    {
        get { return Wrapped.FalseValue; }
        set { Wrapped.FalseValue = value; }
    }
}

This way the converters can be implemented in a more generic manner, and only exactly specified when they are instantiated in XAML:

<conv:NativeBoolToTextConverter x:Key="OnOffConverter" 
    TrueValue="On" FalseValue="Off" />

The added benefit of such an approach to implementing converters is their testability. Because they are portable, they can be tested independently of the target platform, even on platforms with only limited native unit testing support. If you're interested in that, check out my blog post on unit testing Windows Phone applications.

Copyright
Creative Commons License