Pluralizing Value Converter


I often find myself wanting to pluralize text in my applications such as displaying either ‘1 Message’ or ‘2 Messages’. Anyone who has played with Rails will have likely came across the Infector which, among other things, is capable of taking a singular word and returning its plural – message => messages and mouse => mice. Fortunately us in the .NET world can take advantage of the functionality with Infector.NET, a port of the Rails Infector by Andrew Peters. Using this I could simply set the value of my label in code;

messageTextBlock.Text = messages.Count == 1 ? "Message" : Inflector.Pluralize("Message");

A potential down side of this technique is that it won’t cope with the value changing, I would by some means have to handle a changed event and re-run the above code. More problems are that I would have to handle this for every bit of text I wanted to pluralize and I’ve now got the text defined in my code instead of the XAML where I’d ideally be setting the text. So with the awesomeness of WPF Data Binding isn’t there a better way of doing this? Of there is.

Bindings can be assigned a ValueConverter which can modify the value from the data source before being set on the target property. In my case I want to bind to a number and display different text dependent on it’s value. A good question is where do we get this text from, fortunately the Binding object has a ConverterParameter property which will be supplied to the ValueConverter when invoked. Using this the implementation of a PluralizingValueConverter is extremely simple.

public class PluralizingValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var number = (int)value;
        var text = (string)parameter;

        // No need to pluralize if there's only one
        if (number == 1)
            return text;

        return Inflector.Net.Inflector.Pluralize(text);
    }

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

I’ve thrown together an example application which has a simple NumericTextBox I knocked up earlier that exposes a integer Value property. I then have a TextBlock binding it’s Text to the Value of the NumericTextBlock, this binding uses the PluralizingValueConverter and supplies the text it wants to display as a ConverterParameter.

<Window x:Class="PluralizationExample.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:PluralizationExample"
    Title="Pluralization Example" Height="300" Width="300">
    <Window.Resources>
        <local:PluralizingValueConverter x:Key="pluralizingConverter" />
    </Window.Resources>
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <local:NumericTextBox x:Name="numberTextBox" Width="30" Value="3" />
            <TextBlock Text=" blind " />
            <TextBlock Text="{Binding ElementName=numberTextBox, Path=Value, Converter={StaticResource pluralizingConverter}, ConverterParameter='Mouse'}" />
        </StackPanel>
    </StackPanel>
</Window>

As the value of the numeric text is initialised to 3 the application will display the text ‘3 Blind Mice’ when it starts. As expected, changing the value to 1 will cause the text to update which will then read ‘1 Blind Mouse’. Neat.

Mice Mouse

The Inflector class contains a number of other useful methods; such as the Ordinalize method which takes an integer and returns a string of it’s position such as 1 => “1st” and 2 => “2nd”. As with Pluralize it is simple to wrap these in ValueConverters to create a more human interface with very little leg work.

Advertisements

7 thoughts on “Pluralizing Value Converter

  1. Hello there,

    This is a question for the webmaster/admin here at davidpadbury.co.uk.

    Can I use part of the information from your blog post above if I provide a link back to your website?

    Thanks,
    Jack

  2. There’s a area for every sort of personal within this condition. France has several urban centers and areas louis vuitton handbags because both versions features its own historical past, traditions and niche. We promised you won’t ever disappointed louis vuitton shop online uk by our program and our excellent top quality. foakleys http://pinterest.com/foakleys%2

  3. I was recommended this web site by way of my cousin. I
    am now not positive whether this post is written via him as nobody
    else recognise such designated about my difficulty.

    You are wonderful! Thank you!

  4. Wonderful blog you have here but I was curious if you knew of any
    message boards that cover the same topics discussed here?
    I’d really like to be a part of community where I can get advice from other experienced individuals that share the same interest.
    If you have any recommendations, please let me know. Thanks!

  5. Woah! I’m really enjoying the template/theme of this
    blog. It’s simple, yet effective. A lot of times
    it’s challenging to get that “perfect balance” between usability and appearance.
    I must say you have done a excellent job
    with this. Additionally, the blog loads extremely fast for me
    on Opera. Exceptional Blog!

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