Wednesday, June 15, 2011

Silverlight Data Binding Using IValueConverter

Introduction

Silverlight is used for creating rich RIA application. if we wish to bind value in XAML, we are using dependencyproperty and dependencyobject.

One more features of Silverlight for data biniding process is IValueConverter.

IValueConverter is used for formatting and binding data to silverlight XAML control.

Background

When we are binding data to controls there will be times when the data needs to be modified.

a value converter is used in that case and you can re-use your source.

In this article we go through creating converter and code for some value converter examples.

Go Through code

Using Value Converter you can convert

- Boolean value to Visibility of control

- Double value to Percentage

- Double to Opacity of Control

- Numeric to Color of Control

Example 1: Numeric to Color of Control

In my XAML page, i am binding Employee List to itemssource and i want to give background color of each employee different display.

First I am creating one converter to convert numeric value to color brush.

Class : NumericToColorConverter.cs

public class NumericToColorConverter : IValueConverter 
{         
public object Convert(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture)
{             
  Int32 id = System.Convert.ToInt32(value);          
  LinearGradientBrush brush = new LinearGradientBrush();
  brush.StartPoint = new Point(0, 1);         
  brush.EndPoint = new Point(0, 0);         
  brush.GradientStops.Add(new GradientStop()
    { Color = Colors.White, Offset = 0 });
  brush.GradientStops.Add(new GradientStop()         
    { Color = Color.FromArgb
                 (200,
                   System.Convert.ToByte((id * 103) % 256),
                   System.Convert.ToByte((id * 157) % 256),
                   System.Convert.ToByte((id * 233) % 256)
                  ),
                  Offset = 1
        });         
     return brush;     
 }
 public object ConvertBack(object value, Type targetType, object parameter,
    System.Globalization.CultureInfo culture)     
 {             
     throw new NotImplementedException();         }     }  

IValueConverter has Two methods Convert and ConvertBack to convert passed value.

In Convert method

  • first field has value which we passsed from data binding in XAML page.
  • second field is parameter passed as ConverterParamter at the time of biding.
  • third field is used when we are working on globalization.

you can convert Numeric values to SolidColorBrush or LinearGradientBrush.

Converting numeric value to color you have to convert value to bytes in (A,R,G,B) format that is Red,Green and Blue value and A parameter is for Opacity.

my XAML page :

1. first you need to add reference of converter in usercontrol.

 <UserControl x:Class="MyApp:MyTestPage" 
xmlns:converters="MyApp.Library.Converters"                      
mc:Ignorable="d"> 

2. Create key in resource/style for use in page.

<UserControl.Resources>         
 <converters:NumericToColorConverter x:Key="NumericToColorConverter" />
</UserControl.Resources>

3. Bind Data in Control and pass Converter to convert and get back Background Color.

<ItemsControl x:Name="myControl"       
  VerticalAlignment="Top"
  ItemsSource="{Binding Employees}">
             > <ItemsControl.ItemTemplate> 
                         <DataTemplate>
                           <Border BorderThickness="1"          
                           CornerRadius="5"
                           VerticalAlignment="Top"                            
                           BorderBrush="Black"                            
                           Width="150"                            
                           Height="50"                            
                           Margin="0"                            
                           Background="{Binding EmployeeID,
                             Converter={StaticResource NumericToColorConverter}}">
                            <TextBlock Text="{Binding EmployeeName}"
                             FontWeight="Bold"                                 
                           Height="25" /> 
                     </Border>
          </DataTemplate>                                            
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

so, this way you can convert value to your formatted value.

Example 2 : Boolean to Visibility Converter

In this example you are going to read about, you have boolean value (true/false) based on that you return Visibiliy of control (visible/collapsed) from converter.

public class VisibilityConverter : IValueConverter   
{         
  public object Convert(object value, Type targetType, object parameter,
     System.Globalization.CultureInfo culture)       
  {           
     Boolean result = true;              
     if (parameter != null) Boolean.TryParse(parameter.ToString(), out result);              
     if (value != null && value is Boolean)           
     {                 
        if (System.Convert.ToBoolean(value) == result)               
        {                     
           return System.Windows.Visibility.Visible;               
        }
        else               
        {                   
           return System.Windows.Visibility.Collapsed;               
        }           
     }
     return value;       
  }
  public object ConvertBack(object value, Type targetType, object parameter,
    System.Globalization.CultureInfo culture)       
  {           
      throw new NotImplementedException();       
  }   
}   

In above code if you are passing true value at binding source and pass to converter, it will return Visibility.Visible and it value is false it will return Visibility.Collapsed.

You can also pass converter parameter to get result based on passed parameter.

Creating resource

<UserControl.Resources>
<converters:VisibilityConverter x:Key="VisibilityConverter" />     
</UserControl.Resources> 

In XAML Binding

I am binding IsImageVisible property to True.

  <Border Background="White"                   
 Visibility="{Binding Path=IsImageVisible, Converter={StaticResource VisibilityConverter}}">               
   <Image Stretch="Uniform"                      
 HorizontalAlignment="Center"                      
 VerticalAlignment="Center"                      
 Source="/MyApp;component/Resources/Default/Images/abc.jpg" />
</Border>

so, it will return Visibility to Visible.

Now, Using Converter Parameter

In XAML Binding

I am binding IsImageVisible property to True and ConverterParemter to False.

   <Border Background="White"
      Visibility="{Binding Path=IsImageVisible,
           Converter={StaticResource VisibilityConverter},ConverterParameter=False}">               
      <Image Stretch="Uniform"                      
      HorizontalAlignment="Center"                      
      VerticalAlignment="Center"                      
      Source="/MyApp;component/Resources/Default/Images/abc.jpg" />             
 </Border>

Using above code you will get Visibility to Collapsed.

you can use mulitple functionality by passing converterparameter to converter.

Conclusion

In this article you learned how to use a Value Converter class to take data that is in one format and convert it to another format prior to displaying that value in a XAML control.