概要
DataGridでデフォルトのフォーマット以外にしたいことがあります。しかしフォーマットを変えるためだけに、AutoGenerateColumnsを無効にして全ての列を自分で定義するのは面倒です。
1つの解決方法はDataGridのAutoGeneratingColumn
イベントでフォーマットを指定することです。
しかしできればコードビハインドを書きたくないし、複数のDataGridで流用したい、そういう時は添付プロパティが使えます。
添付プロパティ
DateTime
用のDateTimeFormatAutoGenerate
とTimeSpan
用のTimeSpanFormatAutoGenerate
の2つのフォーマットを指定できる添付プロパティが定義されています。
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;
}
}
使用方法
XAML上でフォーマットを指定します。
DataGridOperation.DateTimeFormatAutoGenerate="yy年MM月dd日"
コードビハインドは使用していません。
MainWindow.xaml
<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>
ViewModelは以下のようになります。
MainWindowViewModel.cs
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;
}
環境
VisualStudio 2019 Version 16.8.4
.NET 5
C#9
参考