Posted by: Zeeshan Amjad | March 2, 2010

Conditional Binding


I came across one question on forum that how can we bind one user interface element with more than one property. When the value of first property is not available then use the second one. For example name and nick name property. When name is not available then display the nick name.

We can do this very easily with the help of multi binding and multi value converter. First we have to create one classes inherited by IMultiValueConverter interface. Then we overload the convert method of this class. In the convert method we can specify whatever logic we want. Here is simple implementation of our multi value converter.

  1: public class MyValueConverter : IMultiValueConverter
  2: {
  3:     public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
  4:     {
  5:         String name = values[0] as String;
  6:         String nickName = values[1] as String;
  7: 
  8:         if (name.Length == 0)
  9:             return nickName;
 10:         else
 11:             return name;
 12:     }
 13: 
 14:     public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
 15:     {
 16:         throw new NotImplementedException();
 17:     }
 18: }
 19: 

Here we specify that if the name length is zero then use the nick name. We can specify even more complex logic here. It is important to note that whatever value we are  using in the logic, we have to pass those when defining the multi binding. Here is piece of XAML code to define the multi binding.

  1: <TextBlock Grid.Column="0">
  2: 	<TextBlock.Text>
  3: 		<MultiBinding Converter="{StaticResource MyValueConverterObj}">   
  4: 			<Binding Path="Name"/>
  5: 			<Binding Path="NickName"/>
  6: 		</MultiBinding>
  7: 	</TextBlock.Text>
  8: </TextBlock>
  9: 

Here we define the object of our multi value converter in XAML. Here is a code to create the object of multi value converter in XAML.

  1: <local:MyValueConverter x:Key="MyValueConverterObj"/>

Now lets take a look at the complete program. Here is complete XAML code of our program.

  1: <Window x:Class="WpfConditionalBinding.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:WpfConditionalBinding"
  5:     Title="Conditional Binding" Height="300" Width="300">
  6:     <Window.Resources>
  7:         <local:MyValueConverter x:Key="MyValueConverterObj"/>
  8:     </Window.Resources>
  9:     <Grid>
 10:         <ListBox Margin="5" ItemsSource="{Binding}" HorizontalContentAlignment="Stretch">
 11:             <ListBox.ItemTemplate>
 12:                 <DataTemplate>
 13:                     <Grid>
 14:                         <Grid.ColumnDefinitions>
 15:                             <ColumnDefinition/>
 16:                             <ColumnDefinition/>
 17:                         </Grid.ColumnDefinitions>
 18:                         <TextBlock Grid.Column="0">
 19:                             <TextBlock.Text>
 20:                                 <MultiBinding Converter="{StaticResource MyValueConverterObj}">   
 21:                                     <Binding Path="Name"/>
 22:                                     <Binding Path="NickName"/>
 23:                                 </MultiBinding>
 24:                             </TextBlock.Text>
 25:                         </TextBlock>
 26:                         <TextBlock Grid.Column="1" Text="{Binding Path=Grade}"/>
 27:                     </Grid>
 28:                 </DataTemplate>
 29:             </ListBox.ItemTemplate>
 30:         </ListBox>
 31:     </Grid>
 32: </Window>
 33: 

And here is complete C# coding of our 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 WpfConditionalBinding
 17: {
 18:     /// <summary>
 19:     /// Interaction logic for Window1.xaml
 20:     /// </summary>
 21:     public partial class Window1 : Window
 22:     {
 23:         private List<Student> students = new List<Student>();
 24:         public Window1()
 25:         {
 26:             InitializeComponent();
 27: 
 28:             students.Add(new Student("William", "Bill", "A"));
 29:             students.Add(new Student("", "Sam", "C"));
 30:             students.Add(new Student("Rozi", "Rozi", "B"));
 31:             students.Add(new Student("Sara", "Sara", "A"));
 32:             students.Add(new Student("David", "Dave", "B"));
 33:             students.Add(new Student("", "Sim", "B"));
 34: 
 35:             DataContext = students;
 36:         }
 37:     }
 38: 
 39:     public class MyValueConverter : IMultiValueConverter
 40:     {
 41:         public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
 42:         {
 43:             String name = values[0] as String;
 44:             String nickName = values[1] as String;
 45: 
 46:             if (name.Length == 0)
 47:                 return nickName;
 48:             else
 49:                 return name;
 50:         }
 51: 
 52:         public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
 53:         {
 54:             throw new NotImplementedException();
 55:         }
 56:     }
 57: 
 58:     public class Student
 59:     {
 60:         public Student(String name, String nickName, String grade)
 61:         {
 62:             Name = name;
 63:             NickName = nickName;
 64:             Grade = grade;
 65:         }
 66: 
 67:         public String Name
 68:         { get; set; }
 69: 
 70:         public String NickName
 71:         { get; set; }
 72: 
 73:         public String Grade
 74:         { get; set; }
 75:     }
 76: }
 77: 

This is the output of our program.

ConditionalBinding

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: