Welcome to irritatedVowel.com Sign in | Help

POKE 53280,0: Pete Brown's Blog

Silverlight, WPF, Windows Client Development, Woodworking, .NET Programming, CNC, Nature, and other topics.

A former Microsoft Silverlight MVP and INETA Speaker, Pete Brown writes on a number of topics including Silverlight, WPF, .NET, woodworking and working as a consultant in the DC area. read more

Subscribe

Subscribe to my feed
Add to Technorati Favorites

Community Events


who's online

AddThis Social Bookmark Button

More Uses for Value Converters and Extension Methods in Silverlight Binding

I’m working on a super quick Silverlight 2 application for a restaurant kiosk. We’re using EF and Astoria / ADO.NET Data Services as our data provider, and to structure the client I’m using an implementation of MVVM based on Shawn Wildermuth’s great MSDN article showing how to implement simple MVVM using Silverlight 2. (the article is great in that it doesn’t go nuts trying to solve the command / trigger issue, it just makes the most of what is available and keeps things simple)

I love binding in Silverlight, but sometimes you need to do things with binding that you know how you would do in inline code, but maybe aren’t sure how to handle in binding. Nine times out of ten, a value converter can help you out.

For example, I have a DataGrid full of guests. The grid needs to show the full address for the customer. In order to make the most efficient use of screen space, I want to format that as a single cell, multi-line field. Of course, the data is modeled as separate fields for StreetAddress1, 2, City, State, Zip and Country.

Enter the value converter!

So I wrote a really quick value converter that takes in the whole object and returns back just the formatted address:

public class GuestSingleFieldAddressConverter : IValueConverter
{

    #region IValueConverter Members

    public object Convert(object value, Type targetType, 
                          object parameter, 
                          CultureInfo culture)
    {
        if (!(value is Guests))
            throw new ArgumentException("...", "value");

        Guests guest = (Guests)value;

        StringBuilder builder = new StringBuilder();
        if (!string.IsNullOrEmpty(guest.StreetAddress1)) 
            builder.AppendFormat("{0}\r\n", guest.Address1.Trim());
        if (!string.IsNullOrEmpty(guest.StreetAddress2)) 
            builder.AppendFormat("{0}\r\n", guest.Address2.Trim());

        builder.AppendFormat("{0}, {1} {2}\r\n", 
                                guest.City.TrimEvenNulls(), 
                                guest.State.TrimEvenNulls(), 
                                guest.ZipCode.TrimEvenNulls());
        
        if (!string.IsNullOrEmpty(guest.Country)) 
            builder.AppendFormat("{0}", guest.Country.Trim());


        return builder.ToString();
    }

    public object ConvertBack(object value, Type targetType, 
                              object parameter, 
                              CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}

Very simple. You’ll notice that I also used a simple extension method to take care of formatting null strings:

public static class StringExtensions
{
    public static string TrimEvenNulls(this string source)
    {
        if (source == null)
            return string.Empty;
        else
            return source.Trim();
    }
}

To use this, I then create a Static Resource in my xaml pointing to the value converter (note this is also where my View Model reference lives. Page is a base class I have that inherits from UserControl and adds some UI helper code):

<pages:Page.Resources>
    <vm:GuestsViewModel x:Key="ViewModel" />
    <converters:GuestSingleFieldAddressConverter 
        x:Key="AddressConverter" />
</pages:Page.Resources>

And when binding in the data grid, simply bind to the whole object (don’t specify a path or include a comma) and specify the value converter static resource key:

<data:DataGridTextColumn Header="Mailing Address"
   Width="220"
   FontSize="11"
   Binding="{Binding Converter={StaticResource AddressConverter}}" 
    />

Value Converters don’t solve everything in binding, but they certainly do give you a ton of options for handling different situations. They’re really easy to build and use, plus, I just like having the code for them compartmentalized out in a separate class rather than some function in a screen, or a compound field polluting my model. It makes for cleaner code and easy binding.

  Add to Technorati Favorites
Posted: Saturday, March 07, 2009 2:38 AM by Pete.Brown
Filed under: ,

Comments

DotNetShoutout said:

Thank you for submitting this cool story - Trackback from DotNetShoutout
# March 8, 2009 6:31 PM

Christopher Steen said:

Link Listing - March 8, 2009
# March 9, 2009 1:08 AM

Ben Hayat said:

Hey Pete, since you're using Astoria, Intersoft has developed a great client side Data Source for Astoria that will make your life a lot easier. They also have a great Data Presenter too. I've done research on this product and is really good. Here is the link: http://www.intersoftpt.com/ctp/ Good luck. p.s. If you have any question, the CTO (Andry) is very good at responding.
# March 10, 2009 9:07 PM

Eric said:

works perfectly for one way binding - have you tried implementing twoway?
# July 23, 2009 2:51 PM

Pete.Brown said:

@Eric

I have for other types of conversions, but not for this one. Address parsing is non-trivial, and I haven't had a need to do it in quite some time.

Pete

# July 23, 2009 3:51 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Enter the text you see in the image:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS