WPF - DataContext And IValueConverter Thoughts

I am a total newbie in WPF development. One of the things I wanted to have is to format the values coming out of my domain object into UI, and being able to parse those values back into business objects.

I am coming from a web environment, where no state exists in between requests. I started with an approach usually apply in the web applications, quickly realizing it will not work that way. The fact that DataContext (like a ViewData) is there and doesn't have to be reconstructed is great. The down side - it's not strongly typed. At the same time maybe the only way to use it is one, when assigning the data(object) and that's it. Also bugging the fact that the properties are used for binding as string texts, but that I have to understand better.

Since the DataContext is going nowhere, and it's a reference to domain object, DataBinding done in TwoWay mode (which is the default) assures that any change (as long as it is valid) will propagate back into the domain object (it's property). Converters are another piece of this not so trivial puzzle - they make life easy. By implementing IValueConverter, it is possible to implement the logic for value transformations upon each way of binding. Handy, since it allowed me to decorate currency attributes of my domain object to show currency details on UI, and strip that off and get a plain number when taking the currency value back into the domain object.

The XAML way - not sure I like it completely at this stage. Being able to express binding and converter for the binding in a codeless way is nice. The facts that:

  • You have to create a static resource on each "view" (window/user control) did not sound well
  • The loose control over the binding gives you now firm understanding of what's going on behind the scene

So I started to poke around the idea of using a single converter all over the place. And found it. Again, declaratively, it was a mess, since WPF XAML parse had an issue with it, even though it was compiling. Pure code approach was simple, and XAML parser did not complain.

I put converter into a single location where it can be used by any "view" and it looked like this:

namespace WpfApplication1
{
  public static class Converters
  {
    public static CurrencyConverter CurrencyConverter = new CurrencyConverter();
  }
}

And the code that was doing binding looked like the following snippet:

var binding = new Binding("Amount");
binding.Source = myObject;
binding.Converter = Converters.CurrencyConverter;
txt.SetBinding(TextBox.TextProperty, binding);

The declarative way looked uglier:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:app="clr-namespace:WpfApplication1">
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition />
      <RowDefinition />
    </Grid.RowDefinitions>
        <TextBox Grid.Row="0" 
                     Text="{Binding Path=Amount, Converter={x:Static app:Converters.CurrencyConverter}}" 
                    Height="20" Width="100"></TextBox>
    <Button Grid.Row="1" Name="btn" Height="20" Content="Report value"></Button>
  </Grid>
</Window>

The currency converter is dead simple:

namespace WpfApplication1
{
  [ValueConversion(typeof(double), typeof(string))] 
  public class CurrencyConverter : IValueConverter
  {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
      return ((double) value).ToString("C2", culture);
    }
<span class="kwrd">public</span> <span class="kwrd">object</span> ConvertBack(<span class="kwrd">object</span> <span class="kwrd">value</span>, Type targetType, <span class="kwrd">object</span> parameter, CultureInfo culture)
{
  <span class="kwrd">double</span> result;
  <span class="kwrd">double</span>.TryParse(<span class="kwrd">value</span>.ToString(), NumberStyles.Currency, culture, <span class="kwrd">out</span> result);
  <span class="kwrd">return</span> result;
}

} }

Thoughts, comments, sources for more information are more than appreciated.

1 Comment

Comments have been disabled for this content.