Since it is not a straightforward formatting, as it is the case with dates or with currencies where only the StringFormat class will suffice, here we need to do some additional work to satisfy our requirements.
Example using only the StringFormat to format your DataGrid’s Date and Currency fields:
<DataGridTextColumn Header="My Date" Width="80"
Binding="{Binding Path=MyDate, StringFormat={}{0:dd-MMM-yyyy}}"></DataGridTextColumn>
<DataGridTextColumn Header="Total Amount" Width="80"
Binding="{Binding Path=totalAmount, StringFormat={}{0:C}}"></DataGridTextColumn>
To accomplish the aforementioned combination of date and seconds into a single date and time field, first we need to declare a class that implements the IMultiValueConverter interface. I called this class DoubleSecondsToDateTimeConverter. See the class’ detatils below:
using System;
using System.Windows;using System.Windows.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MultiValueConverterDemo
{
public class DoubleSecondsToDateTimeConverter : IMultiValueConverter
{
#region IMultiValueConverter Members
//**********************************************************************
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
DateTime dtDate;
double dblNumOfSeconds;
if (values[0] != DependencyProperty.UnsetValue)
{dtDate = (DateTime)(values[0]);
}
else
{
return null;
}
if (values[1] != DependencyProperty.UnsetValue)
{dblNumOfSeconds = System.Convert.ToDouble(values[1]);
}
else
{
return dtDate;
}
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
}
I am passing two values to the DoubleSecondsToDateTimeConverter.Convert() from XAML, more precisely from the <Binding> child node of <MultiBinding> (shown in bold):
<DataGrid …>
.
.
.
<DataGridTemplateColumn Header="Data" Width="130" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource dstdConverter}" Mode="OneWay"
StringFormat="{}{0:dd.MM.yyyy hh:mm:ss}">
<Binding Path="DateRecorded" />
<Binding Path="TimestampSec" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
.
.
.
</DataGrid>
When each row is bound to the DataGrid, the parameter array “object[] values” in the implemented Convert() method looks like this:
- values[0] holds the DateRecorded value, e.g. 2011-05-12
The Convert method combines the previously extracted date and seconds by this statement:
DateTime dtNew = dtDate.AddSeconds(dblNumOfSeconds);
And the DateTime value dtNew is returned.
Once this class is complete, it has to be declared as a resource in the Window.Resources collection:
</local:DoubleSecondsToDateTimeConverter>
</Window.Resources>
And then use it in your DataGrid like this:
<DataGrid x:Name="dgTileData" AutoGenerateColumns="False" Width="Auto" MaxHeight="500"
VerticalScrollBarVisibility="Auto" GridLinesVisibility="Horizontal"
Canvas.Left="2"
Canvas.Top="10">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Date & Time Recorded"
Width="130" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource dstdConverter}"
Mode="OneWay" StringFormat="{}{0:dd.MM.yyyy hh:mm:ss}">
<Binding Path="DateRecorded" />
<Binding Path="TimestampSec" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Bearing To Strike" Width="70" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding BearingToStrike}"
HorizontalAlignment="Right" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Strike Type" Width="40" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding StrikeType}"
HorizontalAlignment="Center" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Polarity" Width="65" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding StrikePolarity}"
HorizontalAlignment="Center" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
.
.
.
.
</DataGrid.Columns>
</DataGrid>
The result looks like this:






