WPF MultiValue Converters

MultiValue Converters

A Multivalue Converter is required when your target is bound to multiple sources and if the source and targets have different data formats or need some conversion.

Example 1: assume you have three text box controls and one button control and you want to enable the button control when all the text of the text boxes are filled.

For this case we need to use a Multivalve Converter class that inherits the IMultiValueConverter interface of the System.Windows.Data namespace that will check all the text of the textboxes to determine whether it is filled or not, if it is filled then it will return true otherwise return false and that will enable or disable the button control.

Code Example: pasting: Declaring a Multivalve Converter.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using System.Windows.Data;  
  7.   
  8. namespace ValueConverters  
  9. {  
  10.    public class MultivalueConverter:IMultiValueConverter  
  11.     {  
  12.         public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
  13.         {  
  14.             if (values.Count() >= 2)  
  15.             {  
  16.                 if (string.IsNullOrEmpty(values[0].ToString()) || string.IsNullOrEmpty(values[1].ToString()))  
  17.                     return false;  
  18.                 else return true;  
  19.             }  
  20.             else  
  21.                 return false;  
  22.         }  
  23.   
  24.         public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)  
  25.         {  
  26.             throw new NotImplementedException();  
  27.         }  
  28.     }  
  29. }  

In the preceding code, the convert function checks all the bound data, if any of them are null or empty then it will return false to disable the button control otherwise it will return true to enable the button control. In this example if the text of the two texboxs is found to be empty then the convert function will return false otherwise true.

I have another example for the convert back function. Let's say you have three textboxes, the first TextBox is for taking the first name of a person, the second is for taking the last name and the third one is for displaying the text of the preceding two textboxs jointly with a space between them and vice-versa. In this case the convert back function of IMultiValueConverter interface must be usde. In the following code example of the fullnameconverter class I have used both the convert and convert back functions to do it.

Code Example-2 declaring fullnameconverter class

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using System.Windows.Data;  
  7.   
  8. namespace ValueConverters  
  9. {  
  10.     public class FullNameConverter : IMultiValueConverter  
  11.     {  
  12.         public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
  13.         {  
  14.             if (values != null)  
  15.             {  
  16.                 return values[0] + " " + values[1];  
  17.             }  
  18.             return " ";  
  19.         }  
  20.   
  21.         public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)  
  22.         {  
  23.             string[] values=null;  
  24.             if (value != null)  
  25.                 return values = value.ToString().Split(' ');  
  26.             return values;  
  27.         }  
  28.     }  
  29. }  

The convert function in the preceding code concatenates the two data items coming from the two sources with a space between them and returns the concatenated data to the target. The convert back function splits the concatenated string with a space to an array of strings and returns the items of the array to the corresponding source.

In the preceding scenario the convert back function takes the text of both the first name TextBox and the last name TextBox and concatenates the text with a space between the two texts and returns that to the third TextBox.

Again, when you fill in the data in the third TextBox, the convert back function takes the text and splits it into an array string using a space and returns that to the source textboxes (first name TextBox and last name TextBox).

Use of Converter

To use a converter you need to implement the interface of the converter class in the XAML page of WPF, you need to declare the resource. After declaring the resource it is necessary to use it with binding. See the following XAML code example.

XAML Example

  1. <Window x:Class="ValueConverters.MultiValueConverter"  
  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:ValueConverters"  
  5.         Title="MultiValueConverter" Height="300" Width="448.872">  
  6.     <Window.Resources>  
  7.         <local:MultivalueConverter x:Key="multivalueConverter"></local:MultivalueConverter>  
  8.         <local:FullNameConverter x:Key="fullNameConverter"></local:FullNameConverter>  
  9.     </Window.Resources>  
  10.     <Grid>  
  11.         <TextBlock Text="Value Converter Exampkle" HorizontalAlignment="Stretch" VerticalAlignment="Top" TextAlignment="Center"></TextBlock>  
  12.         <TextBlock Text="First Name" HorizontalAlignment="Left" VerticalAlignment="Top" TextAlignment="Center" Margin="10,38,0,0"></TextBlock>  
  13.         <TextBox Name="txtFirstName" HorizontalAlignment="Left" VerticalAlignment="Top" Height="25" Width="255" Margin="91,29,0,0" ></TextBox>  
  14.         <TextBlock Text="Last Name" HorizontalAlignment="Left" VerticalAlignment="Top" TextAlignment="Center" Margin="11,68,0,0"></TextBlock>  
  15.         <TextBox Name="txtLastName" HorizontalAlignment="Left" VerticalAlignment="Top" Height="25" Width="255" Margin="91,59,0,0" ></TextBox>  
  16.         <TextBlock Text="Full Name" HorizontalAlignment="Left" VerticalAlignment="Top" TextAlignment="Center" Margin="14,105,0,0"></TextBlock>  
  17.         <TextBox Name="txtFullName" HorizontalAlignment="Left" VerticalAlignment="Top" Height="25" Width="332" Margin="14,126,0,0" >  
  18.             <TextBox.Text>  
  19.                 <MultiBinding Converter="{StaticResource fullNameConverter}">  
  20.                     <Binding ElementName="txtFirstName" Path="Text" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"></Binding>  
  21.                     <Binding ElementName="txtLastName" Path="Text" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"></Binding>  
  22.                 </MultiBinding>  
  23.             </TextBox.Text>  
  24.         </TextBox>  
  25.         <Button Content="Click" HorizontalAlignment="Left" VerticalAlignment="Top" Height="23" Width="50" Margin="165,171,0,0">  
  26.             <Button.IsEnabled>  
  27.                 <MultiBinding Converter="{StaticResource multivalueConverter}">  
  28.                     <Binding ElementName="txtFirstName" Path="Text"></Binding>  
  29.                     <Binding ElementName="txtLastName" Path="Text"></Binding>  
  30.                 </MultiBinding>  
  31.             </Button.IsEnabled>  
  32.         </Button>  
  33.     </Grid>  
  34. </Window>  
 
Summary

I hope in this demonstration you have an idea of Multivalue Converters and their use.