Welcome to MSDN Blogs Sign in | Join | Help

IValueConverter: The Swiss Army Knife of Bindings [PropertyViewer sample is a WPF/Silverlight visualization and debugging aid!]

If you've made much use of data binding in WPF or Silverlight, you've probably come across the IValueConverter interface. IValueConverter sits between the data source and destination and gives the developer a chance to examine/alter/replace the data as it flows through the converter. It's been my experience that IValueConverter is a powerful and versatile tool for application developers.

As part of a recent project, I wanted to display some of an object's properties in a simple list. Specifically, I had an instance and I wanted to display a list of "Property Name: Property Value" entries for each property of that object. My background with ListBox led me to naturally think of using ItemsControl for the basis of my property viewer; the ItemsControl content model (with its support for DataTemplates) seemed like a natural fit.

Aside: One of the key things XAML enables is a distinct separation of implementation from representation. By explicitly separating most aspects of how an application looks (XAML) from how it works (code) as part of the developer/designer workflow, WPF and Silverlight help to enforce a level of encapsulation (in the object-oriented programming sense) that makes programs easier to write and maintain. In the ideal world, a program's functionality is entirely expressed in its code - and so it's possible for others to completely change that application's appearance without knowing or caring how it's implemented. Just like the web has CSS restyling contests, WPF has reskinning competitions!

So I knew I wanted to use ItemsControl and I knew I wanted to keep the UI aspects of the property viewer in XAML-space (what it looked like, what properties it displayed, etc.). I started looking at how IValueConverter might help and that led to the solution I describe here. PropertyViewer ends up being quite simple to use - and a good demonstration of the power of IValueConverter!

Here's the comment header from the code:

/// <summary>
/// IValueConverter implementation that expands some/all of an object's
/// public properties as a collection of bindable name/value instances.
/// </summary>
/// <remarks>
/// * Bindable instances are of type PropertyDetails, a contained class
///   that exposes a property's Name and Value as properties.
/// * All public properties are enumerated by default; ConverterParameter
///   can be used to specify which properties will be enumerated (and in
///   which order) by passing a space-delimited list of names.
/// * If DisplayNameAttribute is associated with a property, DisplayName
///   will be used instead of the property name.
/// * PropertyViewer can be used for simple data visualization, debugging
///   of Bindings, and more.
/// </remarks>
/// <example>
/// For ItemsControl/ListBox (accessing the object via DataContext):
///   ItemsSource="{Binding Converter={StaticResource PropertyViewer}}"
/// As above, but with a custom property list:
///   ItemsSource="{Binding Converter={StaticResource PropertyViewer},
///     ConverterParameter='PropertA PropertyB'}}"
/// For ItemsControl/ListBox, but specifying the object via Source:
///   ItemsSource="{Binding Source={StaticResource ObjectInstance}
///     Converter={StaticResource PropertyViewer}}"
/// </example>
public class PropertyViewer : IValueConverter
{ ... }

Like the comment says, it's easy to hook up a PropertyViewer:

<ItemsControl ItemsSource="{Binding Converter={StaticResource PropertyViewer}}"/>

Customizing the PropertyViewer is also easy:

<ItemsControl ItemsSource="{Binding Converter={StaticResource PropertyViewer},
    ConverterParameter='Species EatsBugs RelativeMass'}">

Because the end result is a collection of objects, all the existing ItemsControl knowledge and techniques can be used to completely customize the look and feel of the property viewer!

The examples above came from a simple application I wrote to demonstrate PropertyViewer in action. By design, the exact same XAML and code work on both WPF and Silverlight. To prove it, I attached the complete source code for the combined Visual Studio 2008 solution to this blog (download it from the link at the bottom of this post). The sample displays a list of animals, one default PropertyViewer, and one customized PropertyViewer. Select any animal to find out more about it (note that the PropertyViewer updates automatically when the data source changes).

Here's what it looks like on WPF:

WPF Sample

And on Silverlight:

Silverlight Sample

Thanks to the power of IValueConverter, it's easy to use PropertyViewer to display an object's properties in a customizable way. Additionally, PropertyViewer can help troubleshoot data bindings: just drop one in the target location and you can see the available properties along with their current values. I originally wrote this for my project - but now I hope you can use it in yours!

Published Sunday, May 04, 2008 4:21 PM by Delay
Filed under: ,

Attachment(s): PropertyViewer.zip

Comments

# re: IValueConverter: The Swiss Army Knife of Bindings [PropertyViewer sample is a WPF/Silverlight visualization and debugging aid!]

Tuesday, May 06, 2008 4:57 AM by vgsbs

Cool - I really appreciate you do everything for both Silverlight and WPF.

# May 20th Links: ASP.NET, ASP.NET AJAX, .NET, Visual Studio, Silverlight, WPF

Wednesday, May 21, 2008 1:03 AM by ScottGu's Blog

Apologies for the sparseness of my posting the last few weeks - work and life have been busy here lately

# May 20th Links: ASP.NET, ASP.NET AJAX, .NET, Visual Studio, Silverlight, WPF

Wednesday, May 21, 2008 1:35 AM by BusinessRx Reading List

Apologies for the sparseness of my posting the last few weeks - work and life have been busy here lately.&#160;

# May 20th Links: ASP.NET, ASP.NET AJAX, .NET, Visual Studio, Silverlight, WPF

Wednesday, May 21, 2008 1:50 AM by Mirrored Blogs

Apologies for the sparseness of my posting the last few weeks - work and life have been busy here lately

# Links op 20 mei: ASP.NET, ASP.NET AJAX, .NET, Visual Studio, Silverlight, WPF

Saturday, May 24, 2008 3:35 AM by Scott Guthrie's Blog in Dutch

Mijn verontschuldigingen voor de weinige posts de laatste weken. Mijn werk en leven zijn enorm de druk

# Liens du 20 mai: ASP.NET, ASP.NET AJAX, .NET, Visual Studio, Silverlight, WPF

Tuesday, June 03, 2008 12:41 AM by Scott Guthrie's Blog in French

Mes excuses pour le peu de publications au cours des dernières semaines – le travail et la vie en générale

# May 20th Links: ASP.NET, ASP.NET AJAX, .NET, Visual Studio, Silverlight, WPF

Sunday, June 15, 2008 11:25 AM by Readed By Wrocław NUG members

Apologies for the sparseness of my posting the last few weeks - work and life have been busy here lately

# Question

Friday, July 04, 2008 11:20 AM by Miguel Madero

It's a great example.

Just as a comment, I like the way Ruby On Rails simplify the binding to objects, letting you get friendly names using the Humanize method. That way using an attribute as [DisplayName("Eats Bugs")] is not need just to split the PropertyName based on the case. Altough the attribute gives you more control.

I can see how IValueConverter can be useful in certain escenarios, but most of the time using a FormString would be easier.

I dont know if there's something like that in SL or WPF. I did a trick to do something similar using ValueConverters, it work fine, but I think there should be a sexier solution.

Here's the XAML.

<UserControl.Resources>

      <local:StringFormatConverter x:Name="stringFormatter"/>

  </UserControl.Resources>

  <StackPanel Orientation="Vertical">

      <StackPanel.DataContext>

          <SilverlightApplication3:Person/>

      </StackPanel.DataContext>

      <TextBlock HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Mode=OneWay, Path=Name}" TextWrapping="Wrap"/>

      <TextBlock HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Mode=OneWay, Path=LastName}" TextWrapping="Wrap"/>

      <TextBlock HorizontalAlignment="Left" VerticalAlignment="Top" Text='{Binding Mode=OneWay, Path=DOB, Converter={StaticResource stringFormatter}, ConverterParameter="d"}' TextWrapping="Wrap"/>

      <TextBlock HorizontalAlignment="Left" VerticalAlignment="Top" Text='{Binding Mode=OneWay, Path=Age, Converter={StaticResource stringFormatter}, ConverterParameter="c"}' TextWrapping="Wrap"/>

      <TextBlock HorizontalAlignment="Left" VerticalAlignment="Top" Text='{Binding Mode=OneWay, Path=AnualIncome, Converter={StaticResource stringFormatter}, ConverterParameter="0.00"}' TextWrapping="Wrap"/>

  </StackPanel>

Here's de Code

public class StringFormatConverter:IValueConverter

  {

      #region IValueConverter Members

      public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

      {

          string formatString = parameter.ToString();

          return String.Format("{0:" + formatString + "}", value);

      }

      public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

      {

         throw new NotImplementedException("This Convert supports only OneWay binding");

      }

      #endregion

  }

# re: IValueConverter: The Swiss Army Knife of Bindings [PropertyViewer sample is a WPF/Silverlight visualization and debugging aid!]

Saturday, July 05, 2008 3:01 AM by Delay

Miguel,

Thanks for the kind words - and brief Ruby On Rails lesson! :) I think your approach to string formatting is totally reasonable and it's something I've done once or twice as well. For what it's worth, this scenario should be much easier in WPF 3.5 SP1 because they've added the Binding.StringFormat property (details here: http://blogs.msdn.com/vinsibal/archive/2008/05/16/new-wpf-sp1-feature-data-formatting.aspx). I'm not thinking that'll make it into Silverlight 2, but it sure would be nice!

# Silverlight 文章收集

Monday, July 21, 2008 10:36 PM by 木野狐(Neil Chen)

(以下内容全部整理自博客堂Scottgu博客中文版)Silverlight技巧,诀窍,教程和链接 【原文地址】SilverlightTips,Tricks,...

# Make life a little easier for designers [WPF Triggers with a little less XAML and a little less code]

Friday, September 12, 2008 3:22 AM by Delay's Blog

When I was writing my video frame grabbing sample , I came up with a potentially useful technique for

# Columns of a different color [Customizing the appearance of Silverlight charts with re-templating and MVVM]

Wednesday, February 04, 2009 10:02 AM by Microsoft Weblogs

When we created Silverlight Charting (background reading here and here ), we tried to make things as

# Code improvement suggestion

Monday, February 23, 2009 1:50 PM by vasche

The only comment to the author - stop being a wuss and stop using "null != ..." or "0 == " syntax. Or do you talk in the same way? "if seven dollars costs a beer, then anymore it's not a happy hour". Sheesh...

# Peanut butter jelly time [How to: Create a pleasing visual effect with Silverlight/WPF Charting]

Monday, June 15, 2009 3:14 PM by Delay's Blog

I was recently part of an e-mail thread with Pete Brown discussing the prospects of reproducing Richard

Anonymous comments are disabled
 
Page view tracker