Learning WPF: Using Convertors
June 25, 2007 3:40 am .Net, ReadifyAfter quite some months of working in a web project I finally got around to stay home for a week and start learning again something new: WPF. I only glympsed at my coleagues from Readify that were using WPF and was always amaysed at what you could do with a very small amount of coding.
So, today I started to learn about WPF and … it was a bit harder than expected. First thing that I stumbled upon were the Value Converters. Nice concept when integrating it with Data Binding.
The simple explanation: They allow you to change the value of a data binded element to whatever value you want.
Following Paul’s guidelines I created a “Converter” folder in my project:
Then I declared the converters:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:converters="clr-namespace:WPFDemo.Converter" > <converters:ImagePathConverter x:Key="Converter_ImagePath" /> <converters:PriceConverter x:Key="Converter_PriceConverter" /> </ResourceDictionary>
In a separate resource file: ConverterResources.xml:
Then I included my styles and converters in the App.xaml:
<Application x:Class="Demo.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="Window1.xaml" > <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="\Styles\Styles.xaml"/> <ResourceDictionary Source="\Styles\MediaCenterTheme.xaml"/> <ResourceDictionary Source="\Styles\ConverterResources.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
For me this was actually the hardest part. Figuring out how to merge multiple dictionaries in the app.xaml.
Next step is to implement the converters. I’ll only talk about the ImagePath as the Price one is very basic and I actually copied it and modified it out of Paul’s Trial Balance :)
Here is the simple implementation of the ImagePath Converter:
using System; using System.Collections.Generic; using System.Text; using System.Windows.Data; using System.Windows.Shapes; namespace WPFDemo.Converter { /// <summary> /// Converterts an product image relative path to full path /// </summary> [ValueConversion(typeof(string), typeof(string))] [ValueConversion(typeof(string), typeof(string))] public class ImagePathConverter : IValueConverter { private static string rootImagePath = @"D:\Websites\BestGames\BestGamesWebSite\"; public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value is string) { return System.IO.Path.Combine(rootImagePath, value as string); } return value; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return value; } } }
Then write a user control with a list that will use the converter to bind an image to a path, not directly but via a converter:
<UserControl x:Class="WPFDemo.ImageListUC" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:converters="clr-namespace:WPFDemo.Converter" > <UserControl.Resources> <DataTemplate x:Key="Image"> <StackPanel Orientation="Horizontal"> <Image Source="{Binding Path=ImageName, Converter={StaticResource Converter_ImagePath}}" Width="60" Height="60" /> </StackPanel> </DataTemplate> </UserControl.Resources> <ListView x:Name="_list" ItemsSource="{Binding MyProducts}"> <ListView.View> <GridView> <GridViewColumn Header="" Width="70" CellTemplate="{StaticResource Image}" /> <GridViewColumn Header="Name" Width="250" DisplayMemberBinding="{Binding Path=Name}" /> </GridView> </ListView.View> </ListView> </UserControl>
The bit here to get it working is the Converter declared as part of the Binding <Image Source=”{Binding Path=ImageName, Converter={StaticResource Converter_ImagePath}}” Width=”60″ Height=”60″ />
Compile. Fix compilation errors. Compile again. Run and you should get this:
Very nice and very clean. I start to like WPF.
