2012年7月3日火曜日

[WPF]DataGridのHeaderとCellの水平位置

DataGridColumnHeaderと、その下に続くCellの見た目を編集してみる。
主に幅と、文字の位置とか。

まずはベースのソースから。
<Window x:Class="TestDataGrid.MainWindow"
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           Title="MainWindow" Height="300" Width="400">
    <Window.Resources>
        <Style x:Key="DataListColumnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}">
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Background" Value="#FF232323"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="BorderBrush" Value="Black"/>
            <Setter Property="Padding" Value="5"/>
        </Style>
        <Style x:Key="DataListCellStyle" TargetType="{x:Type DataGridCell}">
            <Style.Triggers>
                <Trigger Property="IsFocused" Value="True">
                    <Setter Property="Background" Value="Black"/>
                    <Setter Property="Foreground" Value="White"/>
                </Trigger>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="DarkGray"/>
                    <Setter Property="Foreground" Value="White"/>
                </Trigger>
            </Style.Triggers>
        </Style>
        <Style x:Key="DataListRowStyle" TargetType="{x:Type DataGridRow}">
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="MediumOrchid"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid>
        <DataGrid x:Name="NameList" AutoGenerateColumns="False"
                    HorizontalAlignment="Left" Margin="10,10,0,0"
                    VerticalAlignment="Top" CanUserAddRows="False"
                    ColumnHeaderStyle="{StaticResource DataListColumnHeaderStyle}"
                    CellStyle="{StaticResource DataListCellStyle}"
                    RowStyle="{StaticResource DataListRowStyle}">
        <DataGrid.Columns>
            <DataGridTextColumn Header="本名" Binding="{Binding Name}" Width="80"/>
            <DataGridTextColumn Header="源氏名" Binding="{Binding StageName}" Width="80"/>
            <DataGridTextColumn Header="指名番号" Binding="{Binding IdNumber}" Width="80"/>
            <DataGridTextColumn Header="登録日" Binding="{Binding Registered}" Width="80"/>
        </DataGrid.Columns>
    </DataGrid>
    <Button Content="読込む" HorizontalAlignment="Left" Height="30" 
                Margin="10,0,0,10" VerticalAlignment="Bottom" Width="77" Click="Button_Click"/>
    </Grid>
</Window>
Headerの幅を指定しています。

このままだと、Headerの文字は左揃えで表示されてしまうので、
これを中心揃えにするのが目標です。

 まず、HeaderのStyleに以下を設定してみました。。。
<Setter Property="HorizontalAlignment" Value="Center"/>
なんだか恥ずかしい感じになりました。
しかも、Gripperがテキストのすぐ脇にべったりくっついてて、サイズ変更すると
意味不明な動きになります。

ここで、Headerの作りを見てみるとこんな構成のようなので、Styleの設定を変更してみました。
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
これでHeaderはOKっす。

次はCellの設定。
Headerでダメだったので、おおかた想像はつくけれど、実験的にCellのStyleに以下を設定。
<Setter Property="HorizontalAlignment" Value="Center"/>

すると、こんな感じ。
なんともトリッキーですね。(HeaderのBorderが見づらいので、色を白に変更)

おとなしくHeaderと同じようにCellのStyleを設定。
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
なんと、ダメでした。。。
Headerと同じって訳ではないらしい。

設定値によってどんな変化があるのかを確認したかったので、
CellのBorderに色をつけて、CellのHorizontalAlignmentを全部試してみた。
HorizontalContentAlignmentはデフォルト値。
HorizontalAlignmentに加えて、HorizontalContentAlingnmentのプロパティを変えてみても、
見た目には反映されず。。。

んー。。。

という訳で、中身を見てみたら。
CellのContentPresenterにはHorizontalAlinment、HorizontalContentAlignmentに対応するプロパティが設定されておらぬようです。

StyleにTemplateのプロパティを追加して、
BorderのHorizontalAlignmentをCellのHorizontalAlignmentにバインド、
ContentPresenterのHorizontalAlignmentをCellのHorizontalContentAlignmentにバインドしてみました。
<Style x:Key="DataListCellStyle" TargetType="{x:Type DataGridCell}">
    <Setter Property="HorizontalAlignment" Value="Stretch"/>
    <Setter Property="HorizontalContentAlignment" Value="Right"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridCell}">
                <Border BorderBrush="{TemplateBinding BorderBrush}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                    <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsFocused" Value="True">
            <Setter Property="Background" Value="Black"/>
            <Setter Property="Foreground" Value="White"/>
        </Trigger>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Background" Value="DarkGray"/>
            <Setter Property="Foreground" Value="White"/>
        </Trigger>
    </Style.Triggers>
</Style>
めでたし、めでたし。
あ。目標はCenter揃えでしたが、違いが見えやすいようにRight揃えにしてしまった。。。


これ以外にスマートな方法があるかもしれないですね。。。

DataTemplateを設定するとかの方が色々設定できるのかも。
CellのContentPresenterがデフォルトでは編集プロパティが少ないというのも、
そういう使い方ですよってことなのかな。

今日は実験でした。

0 件のコメント:

コメントを投稿