When using data binding, we may sometimes want to alter the data before presenting it to user, or we may want to change the appearance of something based on the value of the data. For example, assuming we are binding a date value, we may want to change its formatting, or we may want to change the background color based on whether the date is before or after the current date, or even show something special on certain dates (such as flowers on February 14th).
When we bind a list of items to a control (such as GridView or ListView), we can not edit individual templates of the items. We may also be getting our data from another source, such as a webservice, so we may not have control over the data we receive. So, in order to implement the features I’ve explained on the previous paragraph, we will need to use IValueConverter interface, which provides exactly what we need. In this article, we will be developing a Windows Store application that uses the IValueConverter interface.
We’ll start by opening Visual Studio and creating a new Windows Store Blank App project. I’m naming the project IValueConverterApp.
For this example, we will have a list of students. Our students will have a grade between 0 and 100. Our application will display these students, but their grades will need to be in letters (between FF and AA), the item color will be different based on the grade (100 – 80 will be green, 79 – 60 will be orange, and 59 – 0 will be red), and if the grade is 100 we will put a star next to the student’s name.
First of all, we will place a GridView in MainPage.xaml:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <GridView x:Name="StudentsGridView" Margin="120,100,0,100"/> </Grid>
Then we will create the Student class in MainPage.xaml.cs:
public class Student { public string Name { get; set; } public int Grade { get; set; } }
Next, we will create the converter classes. We will have 3 of them: one will change grades to letters, one will select the color, and one will specify whether the star should be shown. We will place them in MainPage.xaml.cs:
public class GradeToLetterConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { if (value != null) { int grade = (int)value; if (grade >= 90) { return "AA"; } else if (grade >= 85) { return "BA"; } else if (grade >= 80) { return "BB"; } else if (grade >= 75) { return "CB"; } else if (grade >= 70) { return "CC"; } else if (grade >= 65) { return "DC"; } else if (grade >= 60) { return "DD"; } else if (grade >= 50) { return "FD"; } else { return "FF"; } } else { return String.Empty; } } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } } public class GradeToColorConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { if (value != null) { int grade = (int)value; if (grade >= 80) { return "Green"; } else if (grade >= 60) { return "Orange"; // You can also enter hexadecimal values here. } else { return "Red"; } } else { return "Gray"; } } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } } public class GradeToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { if (value != null) { int grade = (int)value; if (grade == 100) { return Visibility.Visible; } else { return Visibility.Collapsed; } } else { return Visibility.Collapsed; } } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } }
As you can see, within these classes we can return anything depending on any condition. We will need to add these classes to the MainPage.xaml like the following:
<Page.Resources> <local:GradeToLetterConverter x:Key="GradeToLetterConverter"/> <local:GradeToColorConverter x:Key="GradeToColorConverter"/> <local:GradeToVisibilityConverter x:Key="GradeToVisibilityConverter"/> </Page.Resources>
Then we will create the ItemTemplate for the GridView, and use the converters. Note that I’ve added a star image named “star.png” at this point to Images folder in the project. You can add whichever image you want.
<GridView x:Name="StudentsGridView" Margin="120,100,0,100"> <GridView.ItemTemplate> <DataTemplate> <Grid Height="110" Width="250" Background="{Binding Grade, Converter={StaticResource GradeToColorConverter}}"> <TextBlock Margin="10,10,10,0" TextWrapping="Wrap" Text="{Binding Name}" VerticalAlignment="Top"/> <TextBlock Margin="10,28,10,0" TextWrapping="Wrap" Text="{Binding Grade, Converter={StaticResource GradeToLetterConverter}}" VerticalAlignment="Top"/> <Image HorizontalAlignment="Left" Height="30" Margin="10,46,0,0" VerticalAlignment="Top" Width="30" Source="Images/star.png" Visibility="{Binding Grade, Converter={StaticResource GradeToVisibilityConverter}}"/> </Grid> </DataTemplate> </GridView.ItemTemplate> </GridView>
You can see here that we used each of these converters for binding the corresponding attribute of the controls. All that remains now is to create a list of students and set the GridView’s source:
public MainPage() { this.InitializeComponent(); createStudents(); } private void createStudents() { List<Student> studentList = new List<Student>(); studentList.Add(new Student() { Name = "Student 1", Grade = 80 }); studentList.Add(new Student() { Name = "Student 2", Grade = 65 }); studentList.Add(new Student() { Name = "Student 3", Grade = 10 }); studentList.Add(new Student() { Name = "Student 4", Grade = 100 }); studentList.Add(new Student() { Name = "Student 5", Grade = 87 }); studentList.Add(new Student() { Name = "Student 6", Grade = 76 }); studentList.Add(new Student() { Name = "Student 7", Grade = 60 }); studentList.Add(new Student() { Name = "Student 8", Grade = 94 }); studentList.Add(new Student() { Name = "Student 9", Grade = 55 }); studentList.Add(new Student() { Name = "Student 10", Grade = 83 }); studentList.Add(new Student() { Name = "Student 11", Grade = 88 }); studentList.Add(new Student() { Name = "Student 12", Grade = 51 }); studentList.Add(new Student() { Name = "Student 13", Grade = 100 }); studentList.Add(new Student() { Name = "Student 14", Grade = 72 }); StudentsGridView.ItemsSource = studentList; }
Our application is complete. If you run it, you will see this:
As you see, IValueConverter is very easy to use and can be really useful in many situations. 🙂
You can download the source code of the application here.