Hi
When working with WPF I always found myself thinking how to handle Data formatting when a WPF control was bound to it. Let’s look at the following example of a window with a TextBlock that displays a DateTime:
1: <Window x:Class="BindingFormat.Window1"
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: Title="Window1" Height="300" Width="300">
5: <Grid>
6: <TextBlock Text="{Binding}"></TextBlock>
7: </Grid>
8: </Window>
And the code behind:
1: public Window1()
2: {
3: InitializeComponent();
4: DateTime d = DateTime.Now;
5: this.DataContext = d;
6: }
Very Simple.
The outcome is this:
But what if we wanted to change the format of the DateTime? Before .NET 3.5 SP1 we had 2 options:
That was the easiest and fastest way to make the data in the UI formatted in the way you wanted let’s say we wanted the DateTime to display like this: 11:49 2/5/2009, we would have done this:
1: public Window1()
2: {
3: InitializeComponent();
4: this.DataContext = this;
5: }
6:
7: public string Now
8: {
9: get
10: {
11: return DateTime.Now.ToString("HH:MM d/M/yyyy");
12: }
13: }
and have the UI bind to the Now property:
1: <Window x:Class="BindingFormat.Window1"
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: Title="Window1" Height="300" Width="300">
5: <Grid>
6: <TextBlock Text="{Binding Now}"></TextBlock>
7: </Grid>
8: </Window>
The outcome is what we wanted:
I don’t like this way of work for 2 reasons:
This is a much better way of work because it solves the 2 problems I had with the Property method of formatting data. Using a converter keeps UI logic in the UI, removes the clutter from the code behind and is reusable.
Here is how we do it:
First we add the converter:
1: public class DateTimeConverter : IValueConverter
2: {
3: #region IValueConverter Members
4:
5: public object Convert(object value, Type targetType, object parameter
6: , System.Globalization.CultureInfo culture)
7: {
8: if (value is DateTime)
9: {
10: DateTime d = (DateTime)value;
11: return d.ToString("HH:MM d/M/yyyy");
12: }
13: return string.Empty;
14: }
15:
16: public object ConvertBack(object value, Type targetType, object parameter
17: , System.Globalization.CultureInfo culture)
18: {
19: throw new NotImplementedException();
20: }
21:
22: #endregion
23: }
Use it with the binding:
1: <Window x:Class="BindingFormat.Window1"
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: xmlns:local="clr-namespace:BindingFormat"
5: Title="Window1" Height="300" Width="300">
6: <Window.Resources>
7: <local:DateTimeConverter x:Key="BindingCVR"/>
8: </Window.Resources>
9: <Grid>
10: <TextBlock Text="{Binding Converter={StaticResource BindingCVR}}"/>
11: </Grid>
12: </Window>
And have the DataContext be DateTime.Now:
1: public Window1()
2: {
3: InitializeComponent();
4: DateTime d = DateTime.Now;
5: this.DataContext = d;
6: }
And the outcome? Just as before:
The only drawback to this method is that it is takes more effort.
But we just got lucky..
In .NET 3.5 SP1 we got the StringFormat option in Binding!
This makes things so much easier All we have to do is have the Binding Expression look like this:
1: <TextBlock Text="{Binding StringFormat='HH:MM d/M/yyyy'}"/>
And that’s it, no extra Properties and ValueConverters.
I could have copied the image again but trust me it gives the same outcome in a much more elegant way.
Do you have a different way of work? let me know.
Enjoy
Amit
We pay for user submitted tutorials and articles that we publish. Anyone can send in a contribution
Learn More
Jmix90 Said on May 29, 2009 :
In fact, this makes 3 options and not 2
!
Amit Said on May 29, 2009 :
Indeed it does
Andres Said on Jun 23, 2009 :
Is this blog dead? Where are the updates?
Amit Said on Jul 12, 2009 :
No not dead
I got married and went on my honeymoon.
Will be back online shortly!
Pallavi Said on Dec 23, 2009 :
Hi
I want to display in Combobox in format “Code - Description”, Code is value member of WPF Combobox. Code & Description are members of class ClassA. I got solution as below: