动态生成WPF DataGrid中日期格式化的需求

31

我们需要在运行时将未知结果集绑定到 WPF DataGrid。其中一些列将包含日期时间值,而我们需要正确格式化这些日期时间字段。在设计时不知道哪些列将是日期时间字段的情况下,我们如何能在运行时格式化这些列?

我们正在使用 DataTable 的 DefaultView 进行绑定到 WPF DataGrid。

8个回答

49

使用StringFormat格式化绑定:

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

我认为这比在代码后面编写代码更好。


1
糟糕.. :( 给我标记错误.. 只有这样才能正常工作: Binding="{Binding Date, StringFormat=\{0:dd-MMM-yyyy\}} - gideon
6
这样做是有效的,但只有在去掉反斜杠后才能使用:Binding="{Binding date, StringFormat={}{0:dd/MM/yyyy}}" - Xenan
1
按照答案所述,这对我有效。 - Jack B Nimble
7
为什么它是最受欢迎的答案我不理解,情况是列是动态的,而你所做的是硬编码的。我有什么遗漏吗?! - Erez
3
这是否意味着你需要在设计时知道列的信息?......与要求相反。 - Disillusioned

33

我已经找到了如何在代码中实现这一点......希望有一种方法可以在XAML中模仿这个。(如果您发现一个可行的XAML示例,请发布。)

要通过代码完成这个操作,请为Grid的AutoGeneratingColumn事件添加事件处理程序,例如:

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
如果您需要其他日期格式: dataGridTextColumn.Binding.StringFormat = "{0:dd.MM.yyyy}"; - paul
((DataGridTextColumn)e.Column).Binding.StringFormat = "{0:d}"; ((DataGridTextColumn)e.Column).Binding.StringFormat = "{0:d}"; - stuicidle
1
这就是答案。其余内容与动态生成无关。(自动生成列开启) - kenjara
一般情况下,当我将AutoGenerateColumns设置为“False”时,我无法使此事件触发。但考虑到事件的名称,这并不令人惊讶。 - PeteH

24

你可以在WPF表单的构造函数中设置区域性文化信息,如下所示:

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

或者你可以在窗口标题标记中包含xml标记xml:lang="en-GB"


哇...我需要找到这个文档在哪里,也许还有更多类似的宝石等待被发现。 - Stefan Schmiedl
有史以来最好的答案之一。永远! - 3-14159265358979323846264

8
<DataGridTextColumn Header="Last update"
    Width="110"
    IsReadOnly="True"
    Binding="{Binding Path=Contact.TimeUpdate, StringFormat={}\{0:dd/MM/yyyy hh:mm\}, Mode=OneWay}" />

7
我会使用一个DataType为Date或DateTime的DataTemplate(根据它将以哪种方式出现)。在DataTemplate中放置一个TextBlock,并在绑定中使用StringFormat。类似这样的东西应该可以工作(未经测试):
<DataTemplate DataType="{x:Type DateTime}">
    <TextBlock Text="{Binding StringFormat={0:d}}"  />
</DataTemplate>

如果你只想在网格中应用此功能

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

能否仅将此模板应用于网格中的DateTime值,而不是窗口/应用程序? - FarrEver
1
是的,请将它放在<Grid.Resources>中。 - Bryan Anderson
Bryan - 我已经把代码放进去了,但是网格仍然以原始格式显示。我甚至创建了一个值转换器来将任何DateTime值格式化为指定的格式。我在格式化程序中设置了断点,但它从未触发过。似乎DateTime类型没有被用作网格中的模板。你对此有什么想法吗?也许我们需要一个DataGridColumn转换器或其他东西。 - FarrEver
在设置网格的ItemSource之后,有没有可能通过代码来实现这个功能? - FarrEver
1
你正在使用哪种DataGridColumn?尝试使用自定义列,并将ContentPresenter用作其模板。这将使用提供的DataTemplate(如果有),否则它将使用一个TextBlock,其中Text属性绑定到对象的ToString方法。 - Bryan Anderson

3

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

这段代码非常完美地工作了。


2

我用这种方式运行。它完美地工作。

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

0

FarrEver在5月11日的回答很好,但是对我来说它并不起作用。我仍然得到美国的mm/dd/yyyy格式,而不是我的德国dd/mm/yyyy格式。因此,我建议找到计算机的区域设置,并在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

参见:我的博客


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接