Posted by: Zeeshan Amjad | October 22, 2009

Using IValueConverter in Data Binding Revisited


We studied the IValueConverter studied now let’s explore it little bit more. This time we are going to introduce the custom attributes and then display that information using IValueConverter. Let’s take a look at this step by step. In first step let’s make custom attribute to define the description of the enumerated type.

  1: [AttributeUsage(AttributeTargets.Field)]
  2: public class DescriptionAttribute : Attribute
  3: {
  4:     public DescriptionAttribute()
  5:     {
  6:     }
  7: 
  8:     public DescriptionAttribute(String description)
  9:     {
 10:         Description = description;
 11:     }
 12: 
 13:     public String Description
 14:     { get; set; }
 15: }
 16: 

And define the attributes of enumerated type.

  1: public enum StateInfo
  2: {
  3:     [Description("Largest state with respect to Population")]
  4:     California,
  5: 
  6:     [Description("Largest state with respect to Area")]
  7:     Alaska,
  8: 
  9:     [Description("Smallest state with respect to Area")]
 10:     RohdeIsland,
 11: 
 12:     [Description("Smallest state with respect to Population")]
 13:     Wyoming
 14: }
 15: 

DescriptionAttributes is already define in System.ComponentModel namespace and if we just define this namespace then we don’t have to create this class.

  1: using System.ComponentModel;

Now in the convert function of IValueConverter we are going to use the reflection class and return that information from Convert function.

  1: FieldInfo field = value.GetType().GetField(value.ToString());
  2: 
  3: DescriptionAttribute[] attribs = (DescriptionAttribute[])field.GetCustomAttributes(typeof(DescriptionAttribute), true);
  4: 

Here is a complete coding of Convert function.

  1: public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  2: {
  3:     if (value != null)
  4:     {
  5:         FieldInfo field = value.GetType().GetField(value.ToString());
  6: 
  7:         DescriptionAttribute[] attribs = (DescriptionAttribute[])field.GetCustomAttributes(typeof(DescriptionAttribute), true);
  8: 
  9:         return attribs[0].Description;
 10:     }
 11:     else
 12:     {
 13:         return value;
 14:     }
 15: }
 16: 

Lets make one more custom attribute to display more information about the state and call is StateDescriptionAttribute. Here is a code of this attribute.

  1: [AttributeUsage(AttributeTargets.Field)]
  2: public class StateDesctiptionAttribute : Attribute
  3: {
  4:     public StateDesctiptionAttribute()
  5:     {
  6:     }
  7: 
  8:     public String Capital
  9:     { get; set; }
 10: 
 11:     public String LargestCity
 12:     { get; set; }
 13: 
 14:     public String TimeZone
 15:     { get; set; }
 16: }
 17: 

And here is the usage of this attribute.

  1: public enum StateInfo
  2: {
  3:     [StateDesctiption(Capital = "Sacramento", LargestCity = "Los Angeles", TimeZone = "Pacific")]
  4:     [Description("Largest state with respect to Population")]
  5:     California,
  6: 
  7:     [StateDesctiption(Capital = "Juneau", LargestCity = "Anchorage", TimeZone = "Alaska")]
  8:     [Description("Largest state with respect to Area")]
  9:     Alaska,
 10: 
 11:     [StateDesctiption(Capital = "Providence", LargestCity = "Providence", TimeZone = "Eastern")]
 12:     [Description("Smallest state with respect to Area")]
 13:     RohdeIsland,
 14: 
 15:     [StateDesctiption(Capital = "Cheyenne", LargestCity = "Cheyenne", TimeZone = "Mountain")]
 16:     [Description("Smallest state with respect to Population")]
 17:     Wyoming
 18: }
 19: 

The XAML of this program is same as before, we only change the height of the window. Here is a complete XAML code of this program.

  1: <Window x:Class="objDataProvider.Window1"
  2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4:     xmlns:System="clr-namespace:System;assembly=mscorlib"
  5:     xmlns:odp="clr-namespace:objDataProvider"
  6:     Title="Combo Inside Tree" Height="400" Width="400">
  7: 
  8:     <Window.Resources>
  9:         <odp:EnumToDescriptionConvertor x:Key="enumtoDescription"/>
 10:         <ObjectDataProvider x:Key="sateInfo"
 11:                     MethodName="GetValues" 
 12:                     ObjectType="{x:Type System:Enum}">
 13:             <ObjectDataProvider.MethodParameters>
 14:                 <x:Type TypeName="odp:StateInfo" />
 15:             </ObjectDataProvider.MethodParameters>
 16:         </ObjectDataProvider>
 17:     </Window.Resources>
 18: 
 19:     <ListBox Margin="5" HorizontalContentAlignment="Stretch" ItemsSource="{Binding Source={StaticResource sateInfo}}">
 20:         <ListBox.ItemTemplate>
 21:             <DataTemplate>
 22:                 <Border Margin="5" BorderBrush="DarkViolet" BorderThickness="2">
 23:                     <StackPanel Margin="5">
 24:                         <TextBlock FontWeight="Bold" Foreground="Blue" Text="{Binding}"/>
 25:                         <TextBlock Text="{Binding Mode=OneWay, Converter={StaticResource enumtoDescription}}"/>
 26:                     </StackPanel>
 27:                 </Border>
 28:             </DataTemplate>
 29:         </ListBox.ItemTemplate>
 30:     </ListBox>
 31: </Window>
 32: 

And here is the complete C# code of this 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.Reflection;
 15: using System.Globalization;
 16: using System.ComponentModel;
 17: 
 18: namespace objDataProvider
 19: {
 20:     /// <summary>
 21:     /// Interaction logic for Window1.xaml
 22:     /// </summary>
 23:     public partial class Window1 : Window
 24:     {
 25:         public Window1()
 26:         {
 27:             InitializeComponent();
 28:         }
 29:     }
 30: 
 31:     [AttributeUsage(AttributeTargets.Field)]
 32:     public class StateDesctiptionAttribute : Attribute
 33:     {
 34:         public StateDesctiptionAttribute()
 35:         {
 36:         }
 37: 
 38:         public String Capital
 39:         { get; set; }
 40: 
 41:         public String LargestCity
 42:         { get; set; }
 43: 
 44:         public String TimeZone
 45:         { get; set; }
 46:     }
 47: 
 48:     [ValueConversion(typeof(Object), typeof(String))]
 49:     public class TestConvertor : IValueConverter
 50:     {
 51:         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
 52:         {
 53:             if (value != null)
 54:             {
 55:                 Enum str = value as Enum;
 56:                 String strValue = str.ToString().ToUpper();
 57:                 return strValue;
 58:             }
 59:             else
 60:                 return value;
 61:         }
 62: 
 63:         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
 64:         {
 65:             return value;
 66:         }
 67:     }
 68: 
 69:     [ValueConversion(typeof(Object), typeof(String))]
 70:     public class EnumToDescriptionConvertor : IValueConverter
 71:     {
 72:         public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
 73:         {
 74:             if (value != null)
 75:             {
 76:                 FieldInfo field = value.GetType().GetField(value.ToString());
 77: 
 78:                 StateDesctiptionAttribute[] attribs = 
 79:                     (StateDesctiptionAttribute[])field.GetCustomAttributes(typeof(StateDesctiptionAttribute), true);
 80: 
 81:                 return String.Format("Caiptal = {0}\nLargest City = {1}\nTimeZone = {2}",
 82:                     attribs[0].Capital, attribs[0].LargestCity, attribs[0].TimeZone);
 83:             }
 84:             else
 85:             {
 86:                 return value;
 87:             }
 88:         }
 89: 
 90:         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
 91:         {
 92:             string strValue = value as string;
 93: 
 94:             return Enum.Parse(typeof(StateInfo), strValue, true);
 95:         }
 96:     }
 97:     
 98:     public enum StateInfo
 99:     {
100:         [StateDesctiption(Capital = "Sacramento", LargestCity = "Los Angeles", TimeZone = "Pacific")]
101:         [Description("Largest state with respect to Population")]
102:         California,
103: 
104:         [StateDesctiption(Capital = "Juneau", LargestCity = "Anchorage", TimeZone = "Alaska")]
105:         [Description("Largest state with respect to Area")]
106:         Alaska,
107: 
108:         [StateDesctiption(Capital = "Providence", LargestCity = "Providence", TimeZone = "Eastern")]
109:         [Description("Smallest state with respect to Area")]
110:         RohdeIsland,
111: 
112:         [StateDesctiption(Capital = "Cheyenne", LargestCity = "Cheyenne", TimeZone = "Mountain")]
113:         [Description("Smallest state with respect to Population")]
114:         Wyoming
115:     }
116: }
117: 

Here is the output of this program.

IValueConverter_05

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: