Originally published on my old Charteris blog

As I said before WPF data binding, along with the various types of triggers, helps keep the minutiae of UI logic out of your “code behind”. I am amazed by what can be done with just XAML, I was fortunate enough to have a conversation with one of the Microsoft Max team a few weeks back and they he was very keen to explain how much can be done in just XAML.

Therefore I try hard, very hard to keep my UI to XAML but sometimes the binding XML is just too simplistic. Imagine this, I am running a UK region Windows OS with UK settings as default, my UI culture is en-GB and my SQL Server is all UK’ed up. I databound to the DateOfBirth property of my person object to find that the WPF would only display the date in US format arrrrggggghhhhhhhh!!!! I know that Microsoft is a US company but their continual defaulting to US formats is annoying.

<TextBlock HorizontalAlignment="Center" Text="{Binding Path=DateOfBirth}"/>

Simple binding to the DateOfBirth property where the DataContext of the TextBlock was an instance of Person

The solution to this situation and any where your binding needs a little help from some good old-fashioned code is a Converter. There are two types of Converters IValueConverter and IMultiValueConveter, IValueConverter is used to convert a single data value to another whereas a MultiValueConveter is used to convert multiple data values to a single value. Both interfaces support two-way binding with the Convert and ConvertBack methods. 

<TextBlock HorizontalAlignment="Center"

            Text="{Binding Path=DateOfBirth, Converter={StaticResource MyDateToShortDateStringConverter}}"/>

Here the TextBlock XAML has changed to include a reference to the converter.

The Convert method simply formats the date to the UK format we required. The display of the UK date was read only so I only needed to worry about Convert, returning Binding.DoNothing (I love that naming) from ConvertBack.

public object Convert(object dataValue, Type type,

                        object parameter, CultureInfo culture)

{

    DateTime date = (DateTime)dataValue;

 

    return string.Format("{0:ddd-MMM-YYYY}", date);

}

One really useful converter that ships with WPF is the BooleanToVisibilityConverter. This simply takes a bound boolean data value and converts it to either Visibility.Collapsed (False) or Visibility.Visible(True) . If the simple databing example from a previous post, we can get bind the Visibility of a section of the UI to the IsChecked property of the ToggleButton.

<Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="300" Width="300">

  <Grid.Resources>

    <BooleanToVisibilityConverter x:Key="BoolToVisConverter"/>

  </Grid.Resources>

  <StackPanel Background="Green">

    <ToggleButton Content="Hide/Show" Margin="5"  Name="HideShowButton" IsChecked="True"/>

    <Border BorderThickness="0.5" BorderBrush="AntiqueWhite" Margin="5"

            Visibility="{Binding ElementName=HideShowButton, Path=IsChecked,

                          Converter={StaticResource BoolToVisConverter}}">

      <Grid Margin="5">

        <Grid.ColumnDefinitions>

          <ColumnDefinition/>

          <ColumnDefinition/>

        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>

          <RowDefinition/>

          <RowDefinition/>

        </Grid.RowDefinitions>

        <Label Content="First Name" HorizontalAlignment="Right" Grid.Row="0" Grid.Column="0"/>

        <TextBox Grid.Row="0" Grid.Column="1"/>

        <Label Content="Last Name" HorizontalAlignment="Right" Grid.Row="1" Grid.Column="0" />

        <TextBox Grid.Row="1" Grid.Column="1"/>

      </Grid>

    </Border>

  </StackPanel>

</Grid>

 

It's getting late now and I need rest so time to go to bed, perhaps tomorrow we will meet IMultiValueConverter...