Charles Petzold

Formatting Strings in XAML

Spring Equinox 2006
New York City

Many .NET classes override ToString to provide a readable and reasonable text rendition of objects. Some also implement versions of ToString with formatting strings that can also be used to format objects in Console.Write and String.Format.

I wanted a flexible way to use these handy formatting strings to display objects that are obtained through XAML bindings, and it dawned on me that what I was really looking for was a conversion of the object into a string that made use of these formatting strings. XAML bindings can include a Converter property to perform conversions on objects obtained through bindings. For this Converter property you need a class that implements the IValueConverter interface. The Convert method is called to convert objects transferred from binding sources to targets, and ConvertBack possibly handles the less-frequent transfer from target to source.

A Convert method that converts an object into a string using a possible formatting string proved to be trivial. Here is FormattedTextConverter.cs. The formatting string is expected as the param argument to Convert. In the binding definition, this is provided by the ConvertParameter property.

The next step was to come up with a binding source. A class that implements the INotifyPropertyChanged interface is good for this purpose because it includes a standard mechanism to notify the binding of changes to the property. The ClockTicker.cs class has a bindable property named DateTime that it implements with a call to DateTime.Now. The class triggers the PropertyChanged event every second to signal the presence of a new DateTime object.

With these two classes, we're ready to code a simple digital clock in XAML. The DigitalClockWindow.xaml file defines a binding between the window Content property and the DateTime property of ClockTicker with a Convert property that references the FormattedTextConverter class and a ConvertParameter of "... {0:T} ..." which is a string you might use for a similar purpose in Console.Write or String.Format.

DigitalClockApp.xaml file and DigitalClock.csproj project files round out the project.

(It's quite annoying, but you can't actually view these XAML file in IE. I have things set up so that XAML files are executed, and that's what IE wants to do even though I've included a type="text/plain" attribute along with the href. But these are not standalone XAML files and cannot be executed. To look at them, you have to right-click the link and download them. Sorry for the inconvenience.)

It is not necessary for the Binding definition to include Convert. If you leave it out, the window will still display the current DateTime but in the default ToString rendition. That's also what you get if you remove the ConvertParameter property.

Watch out: The formatting string in Console.Write and String.Format uses the same curly brackets that XAML uses for markup extension. If you assign ConvertParameter the formatting string of just "{0:T}" you'll have a problem because the XAML parser thinks that's a markup extension. Preface it with a pair of curly brackets: "{}{0:T}".