Reputation: 889
I want to change is the date column from a format "DD/MM/YYYY HH:MM:SS" to "DD.MM.YYYY".
<DataGrid Name="dgBuchung" AutoGenerateColumns="True"
ItemsSource="{Binding}" Grid.ColumnSpan="3" >
<ab:DataGridTextColumn Header="Fecha Entrada" Width="110"
Binding="{Binding date, StringFormat={}{0:dd/MM/yyyy}}" IsReadOnly="True" />
</DataGrid>
Unfortunately that code throws an XMLParseException
.
First of all, is this way of solution possible while using AutoGenerateColumns? If no, how else can I try to handle this?
If yes, what is the problem with the code above?
Upvotes: 78
Views: 136384
Reputation: 21
This is a very old question, but I found a new solution, so I wrote about it.
First of all, is this way of solution possible while using AutoGenerateColumns?
Yes, that can be done with AttachedProperty as follows.
<DataGrid AutoGenerateColumns="True"
local:DataGridOperation.DateTimeFormatAutoGenerate="yy-MM-dd"
ItemsSource="{Binding}" />
There are two AttachedProperty defined that allow you to specify two formats.
DateTimeFormatAutoGenerate
for DateTime
and TimeSpanFormatAutoGenerate
for TimeSpan
.
class DataGridOperation
{
public static string GetDateTimeFormatAutoGenerate(DependencyObject obj) => (string)obj.GetValue(DateTimeFormatAutoGenerateProperty);
public static void SetDateTimeFormatAutoGenerate(DependencyObject obj, string value) => obj.SetValue(DateTimeFormatAutoGenerateProperty, value);
public static readonly DependencyProperty DateTimeFormatAutoGenerateProperty =
DependencyProperty.RegisterAttached("DateTimeFormatAutoGenerate", typeof(string), typeof(DataGridOperation),
new PropertyMetadata(null, (d, e) => AddEventHandlerOnGenerating<DateTime>(d, e)));
public static string GetTimeSpanFormatAutoGenerate(DependencyObject obj) => (string)obj.GetValue(TimeSpanFormatAutoGenerateProperty);
public static void SetTimeSpanFormatAutoGenerate(DependencyObject obj, string value) => obj.SetValue(TimeSpanFormatAutoGenerateProperty, value);
public static readonly DependencyProperty TimeSpanFormatAutoGenerateProperty =
DependencyProperty.RegisterAttached("TimeSpanFormatAutoGenerate", typeof(string), typeof(DataGridOperation),
new PropertyMetadata(null, (d, e) => AddEventHandlerOnGenerating<TimeSpan>(d, e)));
private static void AddEventHandlerOnGenerating<T>(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is DataGrid dGrid))
return;
if ((e.NewValue is string format))
dGrid.AutoGeneratingColumn += (o, e) => AddFormat_OnGenerating<T>(e, format);
}
private static void AddFormat_OnGenerating<T>(DataGridAutoGeneratingColumnEventArgs e, string format)
{
if (e.PropertyType == typeof(T))
(e.Column as DataGridTextColumn).Binding.StringFormat = format;
}
}
<Window
x:Class="DataGridAutogenerateCustom.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DataGridAutogenerateCustom"
Width="400" Height="250">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<StackPanel>
<TextBlock Text="DEFAULT FORMAT" />
<DataGrid ItemsSource="{Binding Dates}" />
<TextBlock Margin="0,30,0,0" Text="CUSTOM FORMAT" />
<DataGrid
local:DataGridOperation.DateTimeFormatAutoGenerate="yy-MM-dd"
local:DataGridOperation.TimeSpanFormatAutoGenerate="dd\-hh\-mm\-ss"
ItemsSource="{Binding Dates}" />
</StackPanel>
</Window>
public class MainWindowViewModel
{
public DatePairs[] Dates { get; } = new DatePairs[]
{
new (){StartDate= new (2011,1,1), EndDate= new (2011,2,1) },
new (){StartDate= new (2020,1,1), EndDate= new (2021,1,1) },
};
}
public class DatePairs
{
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public TimeSpan Span => EndDate - StartDate;
}
Upvotes: 2
Reputation: 16148
Very late to the party here but in case anyone else stumbles across this page...
You can do it by setting the AutoGeneratingColumn handler in XAML:
<DataGrid AutoGeneratingColumn="OnAutoGeneratingColumn" ..etc.. />
And then in code behind do something like this:
private void OnAutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.PropertyType == typeof(System.DateTime))
(e.Column as DataGridTextColumn).Binding.StringFormat = "dd/MM/yyyy";
}
Upvotes: 119
Reputation: 31
first select datagrid and then go to properties find Datagrid_AutoGeneratingColumn and the double click And then use this code
Datagrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if (e.PropertyName == "Your column name")
(e.Column as DataGridTextColumn).Binding.StringFormat = "dd/MMMMMMMMM/yyyy";
if (e.PropertyName == "Your column name")
(e.Column as DataGridTextColumn).Binding.StringFormat = "dd/MMMMMMMMM/yyyy";
}
I try it it works on WPF
Upvotes: 3
Reputation: 7492
I know the accepted answer is quite old, but there is a way to control formatting with AutoGeneratColumns :
First create a function that will trigger when a column is generated :
<DataGrid x:Name="dataGrid" AutoGeneratedColumns="dataGrid_AutoGeneratedColumns" Margin="116,62,10,10"/>
Then check if the type of the column generated is a DateTime and just change its String format to "d" to remove the time part :
private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if(YourColumn == typeof(DateTime))
{
e.Column.ClipboardContentBinding.StringFormat = "d";
}
}
Upvotes: 2
Reputation: 815
If your bound property is DateTime, then all you need is
Binding={Property, StringFormat=d}
Upvotes: 18
Reputation: 4774
Don`t forget to use DataGrid.Columns, all columns must be inside that collection. In my project I format date a little bit differently:
<tk:DataGrid>
<tk:DataGrid.Columns>
<tk:DataGridTextColumn Binding="{Binding StartDate, StringFormat=\{0:dd.MM.yy HH:mm:ss\}}" />
</tk:DataGrid.Columns>
</tk:DataGrid>
With AutoGenerateColumns you won`t be able to contol formatting as DataGird will add its own columns.
Upvotes: 146