Mar 05 2010

Binding a Converter Parameter

There are a lot of situations when you need to bind ConverterParameter value.

Imagine that you have Receipt class with two fields: amount and currency type. And you need to format amount string to something like $1,000.00 or ¥1,000.00 depending on currency type. So the good idea is to use converter to do formatting.

The good way is to have something like AmountFormatter which takes amount and currency type and does the formatting.

Current version of the Silverlight disallowing us to bind Converter Parameter value.  But we could pass whole Reciept object to the formatter and take amount and currency type from it directly. Such formatter could look like this:

public class AmountConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var receipt = value as Receipt;
        if (receipt != null)
        {
            return String.Format("{1}{0:0,0.0}", receipt.Amount, receipt.CurrencyChar);
        }
		return value.ToString();
    }

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

This method is not good cause we tide converter and particular class (in our case it is Receipt). But what could we do?

Ok, we want to have a reusable converter. But we need to pass several values to it at the same time. Then lets simply define an interface which converter is expecting to get:

 

public class AmountConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var data = value as IConverterData
        if (data != null)
        {
            return String.Format("{1}{0:0,0.0}", data.Value, data.CurrencySign);
        }
		return value.ToString();
    }

	... 

	public interface IConverterData
    {
        string Value { get; set; }
        string CurrencySign { get; set; }
    }
}

Now to prepare Receipt class to be used in conjunction with AmountConverter we just need to implement AmountConverter.IConverterData interface.

And the usage will look like this:

<TextBlock Text="{Binding Converter={StaticResource AmountConverter}}"/>

Please not what we binds to the whole object here.

Comments

5/20/2010 9:12:27 AM
kaveh
kaveh
Hi,
Nice Idea. But what if there are more than one AmountValue.
Account.BudgetAmount,
Account.Spent,
Account.ProvisionedAmount.
One interface foreahc property?!
6/1/2010 2:52:00 PM
Andrew Veresov
Hi Kaveh,
In your case you could replace Value property with GetValue(object paramter) method in the IConverterData interface. That method will return particular value depending on supplied parameter.
In xaml you will set parameter value for the converter and the converter simply will pass it to the GetValue method.

Add comment


(Will show your Gravatar icon)

biuquote
  • Comment
  • Preview
Loading