(XAML#18)「DataGrid のテキストデータを右寄せ表示する」
ふたたび、昨日のビューモデルを使ってデータを表示します。今回は、それぞれのカラムに幅(Width)を設定します。ここでは、簡略化のため Gender 項目は除いています。また、ID 項目は編集可能にしています(IsReadOnly="True"を除外)。
[XAML]
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<DataGrid Grid.Row="0"
ItemsSource="{Binding Persons}"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Width="50" Binding="{Binding ID}" />
<DataGridTextColumn Header="Name" Width="100" Binding="{Binding Name}" />
<DataGridTextColumn Header="BirthDate" Width="100" Binding="{Binding BirthDate, StringFormat=yyyy/MM/dd}" />
</DataGrid.Columns>
</DataGrid>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<Button Content="Show Data" Click="Button_Click" />
</StackPanel>
</Grid>
DataGrid で AuroGenerateColumns プロパティを使わない場合、DataGrid.Columns に DataGridTextColumn などを使って定義できますが、このテキストカラムは、表示には TextBlock オブジェクトを、編集には TextBox オブジェクトを使います。したがって、数値表示など、特定のカラムで右寄せ表示したい場合は、これらの要素に右寄せを指定することになります。スタイルを指定するためには、それぞれ ElementStyle、EditingElementStyle というプロパティが用意されているため、たとえば ID 項目を右寄せで表示/編集するためには、次のように記述できます。
[XAML]
<DataGridTextColumn Header="ID" Width="50" Binding="{Binding ID}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="HorizontalAlignment" Value="Right" />
</Style>
</DataGridTextColumn.ElementStyle>
<DataGridTextColumn.EditingElementStyle>
<Style TargetType="{x:Type TextBox}">
<Setter Property="HorizontalContentAlignment" Value="Right" />
</Style>
</DataGridTextColumn.EditingElementStyle>
</DataGridTextColumn>
ここではプロパティ要素構文を使って直接指定しましたが、もちろんリソースを使うことで再利用可能な形で記述できます。また、ElementStyle と EditingElementStyle は、あらかじめ DataGridTextColumn にデフォルトの設定が含まれているため、通常、これらを BasedOn で指定しておきます。
<Window.Resources>
<Style x:Key="TextBlockRightStyle" TargetType="{x:Type TextBlock}"
BasedOn="{x:Static DataGridTextColumn.DefaultElementStyle}">
<Setter Property="HorizontalAlignment" Value="Right" />
</Style>
<Style x:Key="TextBoxRightStyle" TargetType="{x:Type TextBox}"
BasedOn="{x:Static DataGridTextColumn.DefaultEditingElementStyle}">
<Setter Property="HorizontalContentAlignment" Value="Right" />
</Style>
</Window.Resources>
......
<DataGrid Grid.Row="0"
ItemsSource="{Binding Persons}"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Width="50" Binding="{Binding ID}"
ElementStyle="{StaticResource TextBlockRightStyle}"
EditingElementStyle="{StaticResource TextBoxRightStyle}" />
<DataGridTextColumn Header="Name" Width="100" Binding="{Binding Name}" />
<DataGridTextColumn Header="BirthDate" Width="100" Binding="{Binding BirthDate, StringFormat=yyyy/MM/dd}" />
</DataGrid.Columns>
</DataGrid>
このとき、TextBlock や TextBox 型に対するキー(x:Key)なしのスタイルを定義しても DataGridTextColumn で使われる要素のスタイルに自動的には適用されないことに注意してください。DataGridTextColumn などのカラム型は FrameworkElement から継承して“いない”ため、Style を直接適用することはできません。DataGridTextColumn で適用できるスタイルは、これらの要素のスタイルと、CellStyle プロパティ(DataGridCell型)、HeaderStyle プロパティ(DataGridColumnHeader 型)の4つです。CellStyle と HeaderStyle は、DataGridColumn から継承したすべてのカラム要素で使えます。
以下は、すべてのカラムのヘッダーを中央に表示し、セルの背景を淡い黄色に設定しています(ただし、セルが選択されているときは、トリガーを使って選択用のブラシに切り替えています)。
[XAML]
<Window.Resources>
<Style x:Key="HeaderCenterStyle" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
<Style x:Key="CellYellowStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="Background" Value="LightYellow" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Self}}" Value="True">
<Setter Property="Background" Value="{x:Static SystemColors.HighlightBrush}" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="TextBlockRightStyle" TargetType="{x:Type TextBlock}"
BasedOn="{x:Static DataGridTextColumn.DefaultElementStyle}">
<Setter Property="HorizontalAlignment" Value="Right" />
</Style>
<Style x:Key="TextBoxRightStyle" TargetType="{x:Type TextBox}"
BasedOn="{x:Static DataGridTextColumn.DefaultEditingElementStyle}">
<Setter Property="HorizontalContentAlignment" Value="Right" />
</Style>
</Window.Resources>
......
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Width="50" Binding="{Binding ID}"
HeaderStyle="{StaticResource HeaderCenterStyle}"
CellStyle="{StaticResource CellYellowStyle}"
ElementStyle="{StaticResource TextBlockRightStyle}"
EditingElementStyle="{StaticResource TextBoxRightStyle}" />
<DataGridTextColumn Header="Name" Width="100" Binding="{Binding Name}"
HeaderStyle="{StaticResource HeaderCenterStyle}"
CellStyle="{StaticResource CellYellowStyle}"/>
<DataGridTextColumn Header="BirthDate" Width="100"
HeaderStyle="{StaticResource HeaderCenterStyle}"
CellStyle="{StaticResource CellYellowStyle}"
Binding="{Binding BirthDate, StringFormat=yyyy/MM/dd}" />
</DataGrid.Columns>