IValueConverters: A great tool in developing WPF/Silverlight applications

IValueConverters in WPF/Silverlight are a very powerful tool in UI presentation, especially, when following the MVVM pattern. In MVVM, where everything in the View is bounded to some property from ViewModel, IValueConverters come handy because often the properties in the ViewModel do not necessarily return the same data type that the View needs. For instance, we can have a boolean IsVisible property in the ViewModel but the UI controls need a Visibility enumeration (with values Visibility.Collapsed and Visibility.Visible) to properly consume it. The great thing about IValueConverters is that they take an object and return an object, so its upto the innovation of developer to make the most out of them.

In this post, I will be demonstrating the powers of IValueConverters by representing a simple boolean variable, that has just two possible values, in several ways. Here’s a screenshot from the application. The bindings in the left column are two way, thus the change in any one of the controls is immediately reflected in the whole view. Have a look:

ivalueconvertersdemo

The ViewModel class exposes only one boolean property to the View. Here’s the code:

public class SampleViewModel : System.ComponentModel.INotifyPropertyChanged
{
    bool boolProperty;

    public bool BoolProperty
    {
        get { return boolProperty; }
        set { boolProperty = value; RaisePropertyChanged("BoolProperty"); }
    }

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
    }

}

The View consumes the boolean property using:

  • Default Boolean To String Converter (with Values = True, False)
  • Boolean to String Converter (with values = Yes, No)
  • Boolean to String Converter (with values = Start, Stop)
  • Boolean to Brush Converter (with colors Green, Red)
  • Boolean to Opacity Converter (with opacity 100%, 10%)
  • Boolean to FontStyle Converter (with styles Normal, Italic)
  • Boolean to Visibility Converter

Here’s the code for the View:

<UserControl x:Class="IValueConvertersDemo.View.SampleView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:IValueConvertersDemo.ViewModels"
    xmlns:converter="clr-namespace:IValueConvertersDemo.Converters"
    >
    <UserControl.Resources>
        <vm:SampleViewModel x:Key="ViewModel" BoolProperty="True" />
        <converter:BoolToColorConverter x:Key="BoolToColorConverter" />
        <converter:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
        <converter:BoolToStringConverter x:Key="BoolToStringConverter" />
        <converter:BoolToDoubleConverter x:Key="BoolToDoubleConverter" />
        <converter:BoolToFontStyleConverter x:Key="BoolToFontStyleConverter" />
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" DataContext="{StaticResource ViewModel}" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="250" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <StackPanel Grid.Column="0" Margin="10" HorizontalAlignment="Left">
            <TextBlock Margin="10" FontSize="18" Text="Two-way" />
            <CheckBox Margin="10" Content="BoolProperty" IsChecked="{Binding BoolProperty, Mode=TwoWay}" />
            <TextBox Margin="10" Width="100" Text="{Binding BoolProperty, Mode=TwoWay}" />
            <TextBox Margin="10" Width="100" Text="{Binding BoolProperty, Mode=TwoWay, Converter={StaticResource BoolToStringConverter}, ConverterParameter='Yes,No'}" />
            <TextBox Margin="10" Width="100" Text="{Binding BoolProperty, Mode=TwoWay, Converter={StaticResource BoolToStringConverter}, ConverterParameter='Start,Stop'}" />
        </StackPanel>

        <StackPanel Grid.Column="1"  Margin="10">
            <TextBlock Margin="10" FontSize="18" Text="One-way" />
            <StackPanel Margin="10" Orientation="Horizontal">
                <Ellipse Height="50" Width="50" Fill="{Binding BoolProperty, Converter={StaticResource BoolToColorConverter}}" HorizontalAlignment="Left" />
                <TextBlock Margin="5" VerticalAlignment="Center" Text="Color(Green/Red) depending on bool property" />
            </StackPanel>
            <StackPanel Margin="10" Orientation="Horizontal">
                <Rectangle Fill="Blue" Height="50" Width="50" Opacity="{Binding BoolProperty, Converter={StaticResource BoolToDoubleConverter}}" HorizontalAlignment="Left" />
                <TextBlock Margin="5" VerticalAlignment="Center" Text="Opacity(100%/10%) depending on bool property" />
            </StackPanel>
            <TextBlock Margin="10" Text="Fontstyle(Normal/Italic) depending on bool property" FontStyle="{Binding BoolProperty, Converter={StaticResource BoolToFontStyleConverter}}" />
            <TextBlock Margin="10" Text="This text is visible only if bool value is true" Visibility="{Binding BoolProperty, Converter={StaticResource BoolToVisibilityConverter}}" />
        </StackPanel>

    </Grid>
</UserControl>

Notice that a boolean variable can only be assigned two values: True and False. Yet, still, we are able to use that in several different ways. Thus IValueConverters provide endless possibilities in WPF data presentation. Its only upto the brain of developer how to exploit them.

The sourcecode for the various converters is included with the sample application that can be downloaded here. Make sure you rename the file to .zip for extraction.

Advertisements

3 Responses to “IValueConverters: A great tool in developing WPF/Silverlight applications”

  1. Mike Graham Says:

    May be i’m missing the point, but it seems to me like the job of the view model is to make life easy for the view. If this is the case, isn’t it better to create both a bool and a Visibility property (that just wraps the bool) in the view model and then just have a simple binding syntax and no required resource declarations for the value converters?

  2. Syed Mehroz Alam Says:

    Hi Mike,

    Using a wrapped property instead of IValueConverters as you suggest is not always handly. Imagine we have a lot of DataClasses (generated from a WCF or RIA service), each having a DateTime property and we want to display only the Date part in various pages of our Silverlight application. Then it would be cumbersome to create a wrapped property in each of those DataClasses than to use just a single DateConverter in the Binding syntax.

    I hope that makes my point clear.

  3. Peder Olav Says:

    You saved my day. Thanks 🙂


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

%d bloggers like this: