Thursday, February 25, 2010

Shatranj – Setting the Color of BoardSquare(s) based on Position thru Value Converters

Before I jump into code, a few concepts:

  1. XAML works with strings and hence is dynamic
  2. So, how does the XAML parser knows how to coerce strings into appropriate types?

Enter Value Converters.  (Note:  TypeConverters would be introduced when we need them later)

I wouldn’t pretend to be an expert on XAML parser / interpreter.  I’d refer you to Rob Relyea’s excellent post if you want to learn under the hood stuff.  I do recommend you read it.

Silverlight’s (3.0) lacks WPF’s depth of support for TypeConverters.

Aside:  Writing a blog post does clarify how much you do not know!  This is the impression I have had during the course of my sojourn learning Silverlight.  I can’t remember on top of my head now!

namespace Shatranj

{

    public class LocationToColorConverter : IValueConverter

    {

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)

        {

            var source = value as BoardSquare;

            if(source == null) return "Transparent";

            return ((source.Placement.X + source.Placement.Y) % 2 == 0) ? "Azure" : "LightBlue";

        }

 

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)

        {

            throw new NotImplementedException();

        }

    }

}

 

 

Hook the Converter up to the Usercontrol’s Background property:

 

<UserControl x:Class="Shatranj.BoardSquareView"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:Shatranj="clr-namespace:Shatranj" Background="{Binding Converter={StaticResource LocationToColorConverter}}">

<snip>

Note for the ‘StaticResource’ to be accessible, the resource key should be accessible at the node where it’s declared.  In other words, you need to have LocationToColorConverter declared at App.Xaml like this:

    <Application.Resources>

        <Shatranj:LocationToColorConverter x:Key="LocationToColorConverter"/>

    </Application.Resources>

The thing that needs a bit of explanation is the Binding syntax:

{Binding Converter={StaticResource LocationToColorConverter}

It’s as though you’ve written:

{Binding Path=<PropertyName>, Converter={StaticResource LocationToColorConverter}

Looks for the <PropertyName> on the DataContext.  Since we’ve not specified property, the whole DataContext object is passed into the Convert() method.  Since our DataContext here is the BoardSquare object, we can typecast ‘value’ and access properties/methods on it.

Things I don’t like about the above approach:

  • Colors are hardcoded in the converter
  • Ideally this should be supplied by Styles (remember, Cascading Style Sheets?)

No comments: