31

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.

8 Answers 8

49

Format the binding by StringFormat:

<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 code behind pieces of code

Sign up to request clarification or add additional context in comments.

5 Comments

grr.. :( gives me markup errors .. works only like this : Binding="{Binding Date, StringFormat=\{0:dd-MMM-yyyy\}}
This works, but only after removing the \'s: Binding="{Binding date, StringFormat={}{0:dd/MM/yyyy}}"
Works for me as stated in the answer.
I don't understand why it's the favorite answer, the case is that the columns are dynamic and what you did is hard coded. Am I missing something ?!
Doesn't this imply you need to know the columns at design time? ... Contrary to the requirement.
33

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}";
        }
    }
}

4 Comments

or, if you need another date format: dataGridTextColumn.Binding.StringFormat = "{0:dd.MM.yyyy}";
((DataGridTextColumn)e.Column).Binding.StringFormat = "{0:d}";
This is the answer. The rest do not deal with dynamic generation. (auto generate columns on)
Just in the general case, I couldn't make this event fire when I also set AutoGenerateColumns="False". But given the name of the event, not really surprising.
23

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

2 Comments

wow ... I need to find where this is documented, maybe there are more gems like this to be found
One of the best answer ever. EVER!
8
<DataGridTextColumn Header="Last update"
    Width="110"
    IsReadOnly="True"
    Binding="{Binding Path=Contact.TimeUpdate, StringFormat={}\{0:dd/MM/yyyy hh:mm\}, Mode=OneWay}" />

Comments

7

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>

5 Comments

Is it possible to apply this template to just the DateTime values in the Grid and not the window/application?
Yes, throw it in <Grid.Resources>
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.
Is there a way to possibly do this in code after setting the ItemSource on the grid?
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.
3

dataGridTextColumn.Binding.StringFormat = "{0:dd/MM/yyyy}";

worked beautifuly

Comments

2

i run this way. its work complete .

<TextBlock  Text="{Binding Date_start,  StringFormat=\{0:dd-MM-yyyy\}, Mode=OneWay}" />

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.