views:

5317

answers:

5

We are binding an unknown result set to a WPF DataGrid at run time. Some of our columns are going to contain DateTime values and we need to properly format these date time fields. Without knowing which columns are going to be DateTime fields at design time, how are we able to format the columns at runtime?

We are using a DataTable's DefaultView to bind to the WPF DataGrid.

+2  A: 

I would use a DataTemplate with a DataType of Date or DateTime (depending on which it will come through as). Place a TextBlock in the DataTemplate with a StringFormat in the binding.

Something like this should work (untested)

<DataTemplate DataType="{x:Type DateTime}">
    <TextBlock Text="{Binding StringFormat={0:d}}" />
</DataTemplate>

Or if you want it to apply just in the Grid

<wpfToolkit:DataGrid>
    <wpfToolkit:DataGrid.Resources>
     <DataTemplate DataType="{x:Type DateTime}">
      <TextBlock Text="{Binding StringFormat={0:d}}" />
     </DataTemplate>
    </wpfToolkit:DataGrid.Resources>
    ...
</wpfToolkit:DataGrid>
Bryan Anderson
Is it possible to apply this template to just the DateTime values in the Grid and not the window/application?
FarrEver
Yes, throw it in <Grid.Resources>
Bryan Anderson
Bryan - I have the code in there but the grid is still coming up with the original formatting. I even created a value converter to format any DateTime values to a specified format. I placed a breakpoint in the formatter and it never hit the code. Seems like the DateTime type is not being used as a template in the Grid. Any ideas on this? Maybe we need a DataGridColumn converter or something.
FarrEver
Is there a way to possibly do this in code after setting the ItemSource on the grid?
FarrEver
What kind of DataGridColumn are you using? Try using a Custom Column and using a ContentPresenter as the template for it. This will use the supplied DataTemplate if there is one, otherwise it will use a TextBlock with the Text property bound to the object's ToString method.
Bryan Anderson
A: 

I figured out how to do this in code...hopefully there is a way to mimic this in XAML. (Please post if you find a working XAML sample.)

To accomplish this in code, add an event handler for the Grid's AutoGeneratingColumn event, such as:

        private void ResultsDataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
    {
        if (e.PropertyType == typeof(DateTime))
        {
            DataGridTextColumn dataGridTextColumn = e.Column as DataGridTextColumn;
            if (dataGridTextColumn != null)
            {
                dataGridTextColumn.Binding.StringFormat = "{0:d}";
            }
        }
    }
FarrEver
or, if you need another date format: dataGridTextColumn.Binding.StringFormat = "{0:dd.MM.yyyy}";
paul
+5  A: 

Hey

what about

<wpfToolkit:DataGridTextColumn Header="Fecha Entrada" Width="110"  
                                   Binding="{Binding EnterDate,StringFormat={}\{0:dd/MM/yyyy hh:mm\}}" IsReadOnly="True" />

I think it's better than writing bigger pieces of code

Junior Mayhé
A: 

The answer of FarrEver, May 11 is good, but by me it doens't function. i still get American mm/dd/yyy instead my German dd/mm/yyyy. So I propose to find the regional settings of computer and use it in StringFormat

    Private Sub DGrid_AutoGeneratingColumn(ByVal sender As System.Object, ByVal e As Microsoft.Windows.Controls.DataGridAutoGeneratingColumnEventArgs)
    If e.PropertyType Is GetType(DateTime) Then
        Dim dataGridTextColumn As DataGridTextColumn = TryCast(e.Column, DataGridTextColumn)
        If dataGridTextColumn IsNot Nothing Then
            Dim ShortDatePattern As String = System.Globalization.DateTimeFormatInfo.CurrentInfo.ShortDatePattern
            dataGridTextColumn.Binding.StringFormat = "{0:" + ShortDatePattern + "}" '"{0:dd/MM/yyyy}"
        End If
    End If
End Sub

see also: my blog

+1  A: 

Hey you can set the locale culture info in the constructor of the WPF form as

this.Language = XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag);

Or you can include the xml markup xml:lang="en-GB" in the window header markup

Libi James