So data binding really is a great thing, especially when it can go beyond the boundaries of just putting text or numbers into the required fields on a form. I was talking with someone about my current project and they made the distinction between data and information, where information is data that had been converted into some useful form. In essence, that's what the System.Windows.Data.IValueConverter is for in Silverlight and WPF; to take some piece of data and make it meaningful within the current context.
My recent example was from a program I wrote that involved the user uploading some files and then tagging them with the required metadata (Name, Caption for pictures, etc.). I had a validator for saving the information so that I could give the user a warning if something was left incomplete, but I wanted it to be both easier to see and for it to be instantly responsive to changes in the data. The goal was for user to see, at a glance, if all the current files were valid and, if not, which ones needed to be fixed. So I started with the template for the Listbox containing my data files:
1: <ListBox x:Name="PictureListBox">
2: <ListBox.ItemTemplate>
3: <DataTemplate>
4: <Grid>
5: <Grid.ColumnDefinitions>
6: <ColumnDefinition Width="104" />
7: <ColumnDefinition Width="*" />
8: </Grid.ColumnDefinitions>
9: <Rectangle Grid.Column="0"
10: Fill="{Binding IsValid, Converter={StaticResource ValidationConverter}}" />
11: <Image Grid.Column="0" Height="100" Width="100"
12: Source="{Binding Path}" />
13: <StackPanel Grid.Column="1" >
14: <... some other stuff that I'm binding... />
15: </StackPanel>
16: </Grid>
17: </DataTemplate>
18: </ListBox.ItemTemplate>
19: </ListBox>
Each image in the listbox now has a rectangle behind it that will serve as a border. I?m binding the fill property of that rectangle to the IsValid property on my data object. Previously, I might have tried either binding this property to a separate object or, worse yet, including the proper color as another property in my data object. Both of these could work for a small app like mine, but they don't feel right. Hence the converter, which my xaml is made aware of like so:
1: <UserControl.Resources>
2: <my:PictureValidationConverter x:Key="ValidationConverter" />
3: </UserControl.Resources>
and finally the code for the converter:
1: public class PictureValidationConverter:IValueConverter
2: {
3: public object Convert(object value, Type targetType,
4: object parameter, System.Globalization.CultureInfo culture)
5: {
6: if ((bool)value)
7: {
8: return new SolidColorBrush(Colors.Green);
9: }
10: else
11: {
12: return new SolidColorBrush(Colors.Red);
13: }
14: }
15:
16: public object ConvertBack(object value, Type targetType,
17: object parameter, System.Globalization.CultureInfo culture)
18: {
19: throw new NotImplementedException();
20: }
21: }
I actually modified the code to more cleanly fit here. Using a ternary operator, it was a single line of code and all without touching the data object or having to go through some elaborate convulsions to avoid doing so. The best part is that the update is instant; as soon as I've finished entering the data, the object can see if it's valid and the image border goes from red to green.
8836abe8-807f-4f16-8924-cb1147e70a91|0|.0