Posted by: Zeeshan Amjad | January 8, 2010

Passing parameters to Value Converter


Sometimes we need to make two or more value converters those are very similar in logic with each other. One possible solution is to make as much converter as much implementations we need. Other solution is to pass parameter to the converter function and uses the ConverterParameter property class in Binding.

Here is a class diagram of IValueConverter.

IValueConverter

Now lets make one converter class to convert double into Point. Here we are going to convert the current value of slider into point and and uses it as a starting point of linear gradient brush. We uses its parameter for forward and backward moment for starting and ending position of gradient. Here is implementation of our converter class.

  1: public class PointConverter : IValueConverter
  2: {
  3:     public object Convert(object value, Type targetType, 
  4:         object parameter, CultureInfo cultureInfo)
  5:     {
  6:         double currentValue = (double)value;
  7:         String direction = parameter as string;
  8: 
  9:         if (direction == "Forward")
 10:         {
 11:             Point point = new Point(currentValue, currentValue);
 12:             return point;
 13:         }
 14:         else if (direction == "Backward")
 15:         {
 16:             Point point = new Point(1 - currentValue, 1 - currentValue);
 17:             return point;
 18:         }
 19:         else
 20:             return null;
 21:     }
 22: 
 23:     public object ConvertBack(object value, Type targetType,
 24:         object parameter, CultureInfo cultureInfo)
 25:     {
 26:         throw new NotImplementedException();
 27:     }
 28: }
 29: 

We have to use the ConverterParameter property of binding class to pass parameter into the converter. Here is a piece of XAML code to pass parameter to our converter.

  1: <LinearGradientBrush 
  2: 	StartPoint="{Binding ElementName=slider, Path=Value, 
  3: 	Converter={StaticResource pointConverterObj},
  4: 	ConverterParameter='Forward'}"  
  5: 	EndPoint="{Binding ElementName=slider, Path=Value, 
  6: 	Converter={StaticResource pointConverterObj},
  7: 	ConverterParameter='Backward'}">
  8: 	<GradientStop Offset="0" Color="AliceBlue"/>
  9: 	<GradientStop Offset="1" Color="Blue"/>
 10: </LinearGradientBrush>
 11: 

Here we use ElementName to bind it with current value of Slider control. Here is complete XAML code of the program.

  1: <Window x:Class="WpfGradient.Window1"
  2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4:     xmlns:local="clr-namespace:WpfGradient"
  5:     Title="Linear Gradient" Height="300" Width="300">
  6:     <Window.Resources>
  7:         <local:PointConverter x:Key="pointConverterObj"/>
  8:     </Window.Resources>
  9:     <Grid>
 10:         <Grid.RowDefinitions>
 11:             <RowDefinition Height="4*"/>
 12:             <RowDefinition/>
 13:         </Grid.RowDefinitions>
 14:         <Rectangle Grid.Row="0" Name="rectangle" Margin="5">
 15:             <Rectangle.Fill>
 16:                 <LinearGradientBrush 
 17:                     StartPoint="{Binding ElementName=slider, Path=Value, 
 18:                     Converter={StaticResource pointConverterObj},
 19:                     ConverterParameter='Forward'}"  
 20:                     EndPoint="{Binding ElementName=slider, Path=Value, 
 21:                     Converter={StaticResource pointConverterObj},
 22:                     ConverterParameter='Backward'}">
 23:                     <GradientStop Offset="0" Color="AliceBlue"/>
 24:                     <GradientStop Offset="1" Color="Blue"/>
 25:                 </LinearGradientBrush>
 26:             </Rectangle.Fill>
 27:         </Rectangle>
 28:         <Slider Name="slider" Grid.Row="1" Margin="5" Minimum="0" Maximum="1" Value="0"/>
 29:     </Grid>
 30: </Window>
 31: 

Here is complete C# code of the program.

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: using System.Windows;
  6: using System.Windows.Controls;
  7: using System.Windows.Data;
  8: using System.Windows.Documents;
  9: using System.Windows.Input;
 10: using System.Windows.Media;
 11: using System.Windows.Media.Imaging;
 12: using System.Windows.Navigation;
 13: using System.Windows.Shapes;
 14: using System.Globalization;
 15: 
 16: namespace WpfGradient
 17: {
 18:     /// <summary>
 19:     /// Interaction logic for Window1.xaml
 20:     /// </summary>
 21:     public partial class Window1 : Window
 22:     {
 23:         public Window1()
 24:         {
 25:             InitializeComponent();
 26:         }
 27:     }
 28: 
 29:     public class PointConverter : IValueConverter
 30:     {
 31:         public object Convert(object value, Type targetType, 
 32:             object parameter, CultureInfo cultureInfo)
 33:         {
 34:             double currentValue = (double)value;
 35:             String direction = parameter as string;
 36: 
 37:             if (direction == "Forward")
 38:             {
 39:                 Point point = new Point(currentValue, currentValue);
 40:                 return point;
 41:             }
 42:             else if (direction == "Backward")
 43:             {
 44:                 Point point = new Point(1 - currentValue, 1 - currentValue);
 45:                 return point;
 46:             }
 47:             else
 48:                 return null;
 49:         }
 50: 
 51:         public object ConvertBack(object value, Type targetType,
 52:             object parameter, CultureInfo cultureInfo)
 53:         {
 54:             throw new NotImplementedException();
 55:         }
 56:     }
 57: }
 58: 

This is the output of the program.

ConverterParameter_01

If we change the slider position then starting and ending position of linear gradient also changes.

ConverterParameter_02


Responses

  1. Hello,

    Great article. Any examples of passing something more that just a string to the converter parameter?

    Something like this:
    ConverterParameter={Binding ElementName=pictureColumn}

    which gives me an invalid XAML error.

    I have a datagrid with a picture field that binds to a column in a database where the value in the column is the name of a .jpg file.

    I wrote a converter to access the database and return a blob (jpeg image) back to the datagrid. I need the .jpg file name in the picture column in order to pull out the correct image. Make sense?

    But the only examples I have found all use a simple string parameter to the value converter.

    Any suggestions would be greatly appreciated.

    Thanks,
    Victor

    • Hi Victor

      Thanks to like it. ConverterParameter is not a dependency property therefore we can’t use binding with it.

      Regards
      Zeeshan Amjad


Leave a comment

Categories