DataGrid(C# WPF)

C#

記事一覧

Style

DataGridCellのStyleにWidthとHorizontalAlignmentを設定すると効かない

<Style x:Key="ExpenseChartStyle" TargetType="DataGridCell">
    <Setter Property="ContentStringFormat" Value="{}{0:c}"/>
    <Setter Property="HorizontalAlignment" Value="Right"/>
    <Setter Property="Width" Value="70"/>
</Style>

<DataGridTextColumn CellStyle="{StaticResource ExpenseChartStyle}" />

上記を適応した場合、セル内が右寄せにならず、左寄せになる。
Widthの指定をStyleから除けば右寄せになる。
もしくはWidthの指定をDataGridTextColumn 内で直接書けば右寄せに出来る。
なぜ?バグ?

Style.Trigger

DataGrid – MultiTriggerとMultiDataTriggerの混在

MultiTriggerを使いたいが、通常のTriggerとDataTriggerを条件にしたい場合

<Condition Propety="IsSelected" Value="True" />

と書いたらBindingの中身がNullなのでNullExceptionが出る。(設定していないので)
なのでDataTriggerの書き方に合わせて、RelativeSource Selfを設定してやると通常のプロパティも問題なく設定できる。

<Trigger Property="IsSelected" Value="True">
↓
<Condition Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Self}}" Value="true" />

DataGrid – SelectedItemsをTriggerに設定する

SelectedItemsをTriggerにする場合、DataGridを指定する。

例 <DataGrid ElementName=dataGridName>

<Condition Binding="{Binding Path=SelectedItems.Count, RelativeSource={RelativeSource AncestorType=DataGrid}}" Value="1" />
もしくは
<Condition Binding="{Binding Path=SelectedItems.Count, ElementName=dataGridName }" Value="1" />

Header

DataGrid – HeadersVisibility

  • All(Default)
  • Column
  • Row
  • None

DataGrid – Headerの色を変更

<DataGrid>
    <DataGrid.ColumnHeaderStyle>
        <Style TargetType="{x:Type DataGridColumnHeader}">
            <Setter Property="Background" Value="Blue"/>
            <Setter Property="BorderBrush" Value="Black"/>
            <Setter Property="BorderThickness" Value="1"/>
        </Style>
    </DataGrid.ColumnHeaderStyle>
</DataGrid> 

GridLine – 罫線

DataGrid – GridLinesVisibility

縦横の罫線を表示するかしないかを選ぶ。DefaultはAll。
・All
・Horizontal
・Vertical
・None

<DataGrid GridLinesVisibility="Horizontal" />

DataGrid – HorizontalGridLinesBrush / VerticalGridLinesBrush

罫線の色指定。

<DataGrid HorizontalGridLinesBrush="Black" />

Background

DataGrid – AlternatingRowBackground

1行おきに背景色を変更したい場合に設定します。
以下のように記載すると標準のバックグラウンド(通常White)とGrayが交互に並びます。

<DataGrid AlternatingRowBackground="Gray" />

DataGrid – AlternationCount

N行おきにAlternatingRowBackgroundを設定したい場合に使います。

AlternationCountを3にすると、Rowに対してAlternationIndexが0,1,2,0,1,2,,,と振られていきます。
ListViewでは、これをTriggerにしてBackgroundを変更したりできますが、DataGridではAlternatingRowBackground専用っぽいです。

<DataGrid AlternationCount="3" AlternatingRowBackground="Gray" />

Scrollbar – スクロールバー

DataGrid – ScrollViewer

DataGridはテンプレート内にスクロールバーが内蔵されています。
見た目が微妙なのでデザインを変えたいと思うこともあると思いますが、テンプレート内にあるので気軽に編集しにくいです。
簡易的ですが、ScrollViewerでDataGridを囲ってしまうことで、スクロールバーをDataGridの外側に持ってくることができます。

<ScrollViewer>
  <DataGrid />
</ScrollViewer>

ScrollViewerでDataGridを囲むと、DataGridの横にDataGridの高さのスクロールバーが出現する。これによりDataGrid内のスクロールバーは非表示になります。
DataGridの外側に出すことで、自前のStyleも当てやすくなります。
しかし、このスクロールバーでスクロールさせると、DataGridのHeaderもスクロールしてしまうので使い勝手は悪くなります。

DataGrid内のScrollbarを使うとHeaderはスクロールしないので使い勝手はよい。
しかし、Vertical Scrollbarの上やHorizontal Scrollbarの左右は隙間が残り、見た目がよろしくないよね。

DataGrid – Scrollbarの上や左右の隙間を消す

最初に解答を置いておきます。
これをWindow.ResourcesやDataGrid.Resourcesに置けばヘッダー部分がScrollbar部分まで延長するので隙間が埋まったように見えます。問題点としてはセルの境界線が残ることです。

<Style TargetType="{x:Type DataGridColumnHeadersPresenter}">
    <Setter Property="Grid.ColumnSpan" Value="2" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridColumnHeadersPresenter}">
                <Grid>
                    <DataGridColumnHeader IsHitTestVisible="False" Name="PART_FillerColumnHeader"/>
                    <ItemsPresenter/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

上のStyleを理解するにはまず、Microsoft公式のリンクからDataGridのControlTemplateの部分を参照してください。

DataGrid Styles and Templates - WPF .NET Framework
Learn about styles and templates for the Windows Presentation Foundation DataGrid control. Modify the ControlTemplate to give the control a unique appearance.

重要なのはここの記述です。

<Grid.ColumnDefinitions>
  <ColumnDefinition Width="Auto" />
  <ColumnDefinition Width="*" />
  <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
  <RowDefinition Height="Auto" />
  <RowDefinition Height="*" />
  <RowDefinition Height="Auto" />
</Grid.RowDefinitions>

DataGridは実は3カラムからなっています。
RowHeader部分、DataGrid本体部分、Scrollbar部分です。

冒頭のStyleで機能させたいのは以下の部分です。

<Setter Property="Grid.ColumnSpan" Value="2" />

これを当てることで、Header領域とScrollbar領域に跨ってHeaderが描画されます。
Scrollbar上方にあった隙間がHeaderに侵食されるために、見かけ上、ScrollbarがDataGrid領域に移動したように見えるのです。

https://stackoverflow.com/questions/21564631/how-to-modify-the-placement-of-datagrid-vertical-scroll-bar-in-wpf)
https://stackoverflow.com/questions/9412114/is-it-possible-to-stop-the-vertical-scrollbar-from-pushing-the-datagrid-columns
https://stackoverflow.com/questions/24453443/datagridcolumnheader-style

DataGrid – スクロール下端の余分なスペースを消す

ScrollViewer.CanContentScroll=”True”
仮想化して論理スクロール。これがDefaultで設定されています。
論理スクロールというのが曲者で、1行単位がきちんと表示されるようにスクロールしてくれますが、これが原因でスクロール下端に余分なスペースができてしまいます。

ScrollViewer.CanContentScroll=”False”
仮想化せずに物理スクロール。こうすることでピクセル単位でのスクロールとなり、下端には無駄な隙間はできなくなります。
ただし、動作が非常に重い。非推奨

VirtualizingPanel.ScrollUnit=”Pixel”
仮想化したまま物理スクロール。
推奨。軽い上に画面下端に余白がでない。
なおCanContentScrollはTrueの必要がある。省略すればDefaultがTrueです。

<DataGrid VirtualizingPanel.ScrollUnit="Pixel" />

コメント