Silverlight projects I’ve been a part of tend to develop a robust set of converters. Anything I can do to keep my view model in a relatively pure state (see Part 0 for more details) keeps me happy. However there are times when I also don’t want to write a converter for one simple “throw-away” data conversion. I know I’m not likely to reuse this and I know I also don’t want to change my view model for this one conversion either. Instead, I’ve been using a simple “Code behind converter” where you can specify your conversion code in the code behind of your view.
1 | <span style="color:#606060" id="lnum1"> 1:</span> <span style="color:#0000ff">using</span> System; |
1 | <span style="color:#606060" id="lnum2"> 2:</span> <span style="color:#0000ff">using</span> System.Globalization; |
1 | <span style="color:#606060" id="lnum3"> 3:</span> <span style="color:#0000ff">using</span> System.Windows.Data; |
1 | <span style="color:#606060" id="lnum4"> 4:</span> |
1 | <span style="color:#606060" id="lnum5"> 5:</span> <span style="color:#0000ff">namespace</span> SilverlightApplication5 { |
1 | <span style="color:#606060" id="lnum6"> 6:</span> <span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> CodeBehindConverter : IValueConverter { |
1 | <span style="color:#606060" id="lnum7"> 7:</span> <span style="color:#0000ff">public</span> <span style="color:#0000ff">event</span> EventHandler<ConverterEventArgs> Convert = <span style="color:#0000ff">delegate</span> { }; |
1 | <span style="color:#606060" id="lnum8"> 8:</span> <span style="color:#0000ff">public</span> <span style="color:#0000ff">event</span> EventHandler<ConverterEventArgs> ConvertBack = <span style="color:#0000ff">delegate</span> { }; |
1 | <span style="color:#606060" id="lnum9"> 9:</span> |
1 | <span style="color:#606060" id="lnum10"> 10:</span> <span style="color:#0000ff">object</span> IValueConverter.Convert( <span style="color:#0000ff">object</span> <span style="color:#0000ff">value</span>, Type targetType, <span style="color:#0000ff">object</span> parameter, CultureInfo culture ) { |
1 | <span style="color:#606060" id="lnum11"> 11:</span> ConverterEventArgs args = <span style="color:#0000ff">new</span> ConverterEventArgs( <span style="color:#0000ff">value</span>, targetType, culture ); |
1 | <span style="color:#606060" id="lnum12"> 12:</span> Convert( <span style="color:#0000ff">this</span>, args ); |
1 | <span style="color:#606060" id="lnum13"> 13:</span> |
1 | <span style="color:#606060" id="lnum14"> 14:</span> <span style="color:#0000ff">return</span> args.ConvertedValue; |
1 | <span style="color:#606060" id="lnum15"> 15:</span> } |
1 | <span style="color:#606060" id="lnum16"> 16:</span> |
1 | <span style="color:#606060" id="lnum17"> 17:</span> <span style="color:#0000ff">object</span> IValueConverter.ConvertBack( <span style="color:#0000ff">object</span> <span style="color:#0000ff">value</span>, Type targetType, <span style="color:#0000ff">object</span> parameter, CultureInfo culture ) { |
1 | <span style="color:#606060" id="lnum18"> 18:</span> ConverterEventArgs args = <span style="color:#0000ff">new</span> ConverterEventArgs( <span style="color:#0000ff">value</span>, targetType, culture ); |
1 | <span style="color:#606060" id="lnum19"> 19:</span> ConvertBack( <span style="color:#0000ff">this</span>, args ); |
1 | <span style="color:#606060" id="lnum20"> 20:</span> |
1 | <span style="color:#606060" id="lnum21"> 21:</span> <span style="color:#0000ff">return</span> args.ConvertedValue; |
1 | <span style="color:#606060" id="lnum22"> 22:</span> } |
1 | <span style="color:#606060" id="lnum23"> 23:</span> } |
1 | <span style="color:#606060" id="lnum24"> 24:</span> |
1 | <span style="color:#606060" id="lnum25"> 25:</span> <span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> ConverterEventArgs : EventArgs { |
1 | <span style="color:#606060" id="lnum26"> 26:</span> <span style="color:#0000ff">public</span> <span style="color:#0000ff">object</span> Value { get; <span style="color:#0000ff">private</span> set; } |
1 | <span style="color:#606060" id="lnum27"> 27:</span> <span style="color:#0000ff">public</span> <span style="color:#0000ff">object</span> ConvertedValue { get; set; } |
1 | <span style="color:#606060" id="lnum28"> 28:</span> <span style="color:#0000ff">public</span> CultureInfo Culture { get; <span style="color:#0000ff">private</span> set; } |
1 | <span style="color:#606060" id="lnum29"> 29:</span> <span style="color:#0000ff">public</span> Type TargetType { get; <span style="color:#0000ff">private</span> set; } |
1 | <span style="color:#606060" id="lnum30"> 30:</span> |
1 | <span style="color:#606060" id="lnum31"> 31:</span> <span style="color:#0000ff">public</span> ConverterEventArgs( <span style="color:#0000ff">object</span> <span style="color:#0000ff">value</span>, Type targetType, CultureInfo culture ) { |
1 | <span style="color:#606060" id="lnum32"> 32:</span> TargetType = targetType; |
1 | <span style="color:#606060" id="lnum33"> 33:</span> Value = <span style="color:#0000ff">value</span>; |
1 | <span style="color:#606060" id="lnum34"> 34:</span> ConvertedValue = <span style="color:#0000ff">value</span>; |
1 | <span style="color:#606060" id="lnum35"> 35:</span> } |
1 | <span style="color:#606060" id="lnum36"> 36:</span> } |
1 | <span style="color:#606060" id="lnum37"> 37:</span> } |
This converter simply provides a Convert and ConvertBack event that can be handled on the code behind.
For an example of it in use, here is a business entity (which has a status enumeration):
1 | <span style="color:#606060" id="lnum1"> 1:</span> <span style="color:#0000ff">namespace</span> SilverlightApplication5 { |
1 | <span style="color:#606060" id="lnum2"> 2:</span> <span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> BusinessEntity { |
1 | <span style="color:#606060" id="lnum3"> 3:</span> <span style="color:#0000ff">public</span> BusinessEnumeration Status { get; set; } |
1 | <span style="color:#606060" id="lnum4"> 4:</span> } |
1 | <span style="color:#606060" id="lnum5"> 5:</span> |
1 | <span style="color:#606060" id="lnum6"> 6:</span> <span style="color:#0000ff">public</span> <span style="color:#0000ff">enum</span> BusinessEnumeration { |
1 | <span style="color:#606060" id="lnum7"> 7:</span> OperationNotCompleted, |
1 | <span style="color:#606060" id="lnum8"> 8:</span> OperationPending, |
1 | <span style="color:#606060" id="lnum9"> 9:</span> OperationWorking, |
1 | <span style="color:#606060" id="lnum10"> 10:</span> OperationCompleted |
1 | <span style="color:#606060" id="lnum11"> 11:</span> } |
1 | <span style="color:#606060" id="lnum12"> 12:</span> } |
And here is a view model for a business view:
1 | <span style="color:#606060" id="lnum1"> 1:</span> <span style="color:#0000ff">namespace</span> SilverlightApplication5 { |
1 | <span style="color:#606060" id="lnum2"> 2:</span> <span style="color:#0000ff">public</span> <span style="color:#0000ff">class</span> BusinessViewModel { |
1 | <span style="color:#606060" id="lnum3"> 3:</span> <span style="color:#0000ff">private</span> BusinessEntity _entity; |
1 | <span style="color:#606060" id="lnum4"> 4:</span> |
1 | <span style="color:#606060" id="lnum5"> 5:</span> <span style="color:#0000ff">public</span> BusinessEnumeration Status { |
1 | <span style="color:#606060" id="lnum6"> 6:</span> get { <span style="color:#0000ff">return</span> _entity.Status; } |
1 | <span style="color:#606060" id="lnum7"> 7:</span> } |
1 | <span style="color:#606060" id="lnum8"> 8:</span> |
1 | <span style="color:#606060" id="lnum9"> 9:</span> <span style="color:#0000ff">public</span> BusinessViewModel() { |
1 | <span style="color:#606060" id="lnum10"> 10:</span> _entity = <span style="color:#0000ff">new</span> BusinessEntity() { |
1 | <span style="color:#606060" id="lnum11"> 11:</span> Status = BusinessEnumeration.OperationPending |
1 | <span style="color:#606060" id="lnum12"> 12:</span> }; |
1 | <span style="color:#606060" id="lnum13"> 13:</span> } |
1 | <span style="color:#606060" id="lnum14"> 14:</span> } |
1 | <span style="color:#606060" id="lnum15"> 15:</span> } |
And here is the view that displays a friendly version of the status enumeration:
1 | <span style="color:#606060" id="lnum1"> 1:</span> <span style="color:#0000ff"><</span><span style="color:#800000">UserControl</span> <span style="color:#ff0000">x:Class</span><span style="color:#0000ff">="SilverlightApplication5.BusinessView"</span> |
1 | <span style="color:#606060" id="lnum2"> 2:</span> <span style="color:#ff0000">xmlns</span><span style="color:#0000ff">="http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span> |
1 | <span style="color:#606060" id="lnum3"> 3:</span> <span style="color:#ff0000">xmlns:x</span><span style="color:#0000ff">="http://schemas.microsoft.com/winfx/2006/xaml"</span> |
1 | <span style="color:#606060" id="lnum4"> 4:</span> <span style="color:#ff0000">xmlns:d</span><span style="color:#0000ff">="http://schemas.microsoft.com/expression/blend/2008"</span> |
1 | <span style="color:#606060" id="lnum5"> 5:</span> <span style="color:#ff0000">xmlns:mc</span><span style="color:#0000ff">="http://schemas.openxmlformats.org/markup-compatibility/2006"</span> |
1 | <span style="color:#606060" id="lnum6"> 6:</span> <span style="color:#ff0000">xmlns:local</span><span style="color:#0000ff">="clr-namespace:SilverlightApplication5"</span><span style="color:#0000ff">></span> |
1 | <span style="color:#606060" id="lnum7"> 7:</span> <span style="color:#0000ff"><</span><span style="color:#800000">UserControl.Resources</span><span style="color:#0000ff">></span> |
1 | <span style="color:#606060" id="lnum8"> 8:</span> <span style="color:#0000ff"><</span><span style="color:#800000">local:CodeBehindConverter</span> <span style="color:#ff0000">x:Key</span><span style="color:#0000ff">="StatusConverter"</span> <span style="color:#ff0000">Convert</span><span style="color:#0000ff">="ConvertStatus"</span><span style="color:#0000ff">></</span><span style="color:#800000">local:CodeBehindConverter</span><span style="color:#0000ff">></span> |
1 | <span style="color:#606060" id="lnum9"> 9:</span> <span style="color:#0000ff"></</span><span style="color:#800000">UserControl.Resources</span><span style="color:#0000ff">></span> |
1 | <span style="color:#606060" id="lnum10"> 10:</span> <span style="color:#0000ff"><</span><span style="color:#800000">UserControl.DataContext</span><span style="color:#0000ff">></span> |
1 | <span style="color:#606060" id="lnum11"> 11:</span> <span style="color:#0000ff"><</span><span style="color:#800000">local:BusinessViewModel</span><span style="color:#0000ff">></</span><span style="color:#800000">local:BusinessViewModel</span><span style="color:#0000ff">></span> |
1 | <span style="color:#606060" id="lnum12"> 12:</span> <span style="color:#0000ff"></</span><span style="color:#800000">UserControl.DataContext</span><span style="color:#0000ff">></span> |
1 | <span style="color:#606060" id="lnum13"> 13:</span> <span style="color:#0000ff"><</span><span style="color:#800000">Grid</span> <span style="color:#ff0000">x:Name</span><span style="color:#0000ff">="LayoutRoot"</span> <span style="color:#ff0000">Background</span><span style="color:#0000ff">="White"</span><span style="color:#0000ff">></span> |
1 | <span style="color:#606060" id="lnum14"> 14:</span> <span style="color:#0000ff"><</span><span style="color:#800000">TextBlock</span> <span style="color:#ff0000">Text</span><span style="color:#0000ff">="{Binding Status, Converter={StaticResource StatusConverter}}"</span><span style="color:#0000ff">></</span><span style="color:#800000">TextBlock</span><span style="color:#0000ff">></span> |
1 | <span style="color:#606060" id="lnum15"> 15:</span> <span style="color:#0000ff"></</span><span style="color:#800000">Grid</span><span style="color:#0000ff">></span> |
1 | <span style="color:#606060" id="lnum16"> 16:</span> <span style="color:#0000ff"></</span><span style="color:#800000">UserControl</span><span style="color:#0000ff">></span> |
And here is the view’s code behind:
1 | <span style="color:#606060" id="lnum1"> 1:</span> <span style="color:#0000ff">using</span> System.Windows.Controls; |
1 | <span style="color:#606060" id="lnum2"> 2:</span> |
1 | <span style="color:#606060" id="lnum3"> 3:</span> <span style="color:#0000ff">namespace</span> SilverlightApplication5 { |
1 | <span style="color:#606060" id="lnum4"> 4:</span> <span style="color:#0000ff">public</span> <span style="color:#0000ff">partial</span> <span style="color:#0000ff">class</span> BusinessView : UserControl { |
1 | <span style="color:#606060" id="lnum5"> 5:</span> <span style="color:#0000ff">public</span> BusinessView() { |
1 | <span style="color:#606060" id="lnum6"> 6:</span> InitializeComponent(); |
1 | <span style="color:#606060" id="lnum7"> 7:</span> } |
1 | <span style="color:#606060" id="lnum8"> 8:</span> |
1 | <span style="color:#606060" id="lnum9"> 9:</span> <span style="color:#0000ff">private</span> <span style="color:#0000ff">void</span> ConvertStatus( <span style="color:#0000ff">object</span> sender, ConverterEventArgs e ) { |
1 | <span style="color:#606060" id="lnum10"> 10:</span> <span style="color:#0000ff">switch</span>( (BusinessEnumeration) e.Value ) { |
1 | <span style="color:#606060" id="lnum11"> 11:</span> <span style="color:#0000ff">case</span> BusinessEnumeration.OperationNotCompleted: |
1 | <span style="color:#606060" id="lnum12"> 12:</span> e.ConvertedValue = <span style="color:#006080">"Not completed"</span>; |
1 | <span style="color:#606060" id="lnum13"> 13:</span> <span style="color:#0000ff">break</span>; |
1 | <span style="color:#606060" id="lnum14"> 14:</span> <span style="color:#0000ff">case</span> BusinessEnumeration.OperationPending: |
1 | <span style="color:#606060" id="lnum15"> 15:</span> e.ConvertedValue = <span style="color:#006080">"Pending"</span>; |
1 | <span style="color:#606060" id="lnum16"> 16:</span> <span style="color:#0000ff">break</span>; |
1 | <span style="color:#606060" id="lnum17"> 17:</span> <span style="color:#0000ff">case</span> BusinessEnumeration.OperationWorking: |
1 | <span style="color:#606060" id="lnum18"> 18:</span> e.ConvertedValue = <span style="color:#006080">"Working"</span>; |
1 | <span style="color:#606060" id="lnum19"> 19:</span> <span style="color:#0000ff">break</span>; |
1 | <span style="color:#606060" id="lnum20"> 20:</span> <span style="color:#0000ff">case</span> BusinessEnumeration.OperationCompleted: |
1 | <span style="color:#606060" id="lnum21"> 21:</span> e.ConvertedValue = <span style="color:#006080">"Complete"</span>; |
1 | <span style="color:#606060" id="lnum22"> 22:</span> <span style="color:#0000ff">break</span>; |
1 | <span style="color:#606060" id="lnum23"> 23:</span> } |
1 | <span style="color:#606060" id="lnum24"> 24:</span> } |
1 | <span style="color:#606060" id="lnum25"> 25:</span> } |
1 | <span style="color:#606060" id="lnum26"> 26:</span> } |
If it turns out you need this elsewhere, it’s easy to change this into its own converter because you followed the same approach as you would have when needing a converter in the first place. Move the code into a custom IValueConverter class and update your usages of this to your new converter.