WPFのDataGridヘッダーを2段組にする方法

簡単にできるかなと思って手をつけたのですが案外大変です。

最初のDataGrid

まずは出発点となるDataGridですが以下のような3つの列を持つものです。

ヘッダーを2段にする

ヘッダーを2段にする方法をまず検索したところいくつかアイデアが見つかりました。大まかに分けてDataGridのDataGridColumnHeaderのレイアウトと変える方法とDataGridの上部にGridを配置する方法です。どちらも試した見たのですが、後者の方がColumnSpanがし易そうなので採用しました。
WPF multi-column super headerを参考にコードを追加しました。

Elementバインドを利用してDataGridのリサイズにも対応できています。しかし問題があります。まず横スクロールに対応していません。また上部ヘッダーでカラムのリサイズ機能が利用ができないです。順番に対処をしていきます。

横スクロールを連動する

下部の横スクロールにあわせ上部を移動させる方法ですが、これはScrollViewerを連動させる手法で解決できそうです。Scroll Synchronizationで紹介されている方法と同様の仕組みを用意して対処します。


上部ヘッダーのカラムリサイズ機能を実装する

この機能を実装するためには上部ヘッダーにまずはThumbを配置します。DataGridのThumbのスタイルはDataGrid のスタイルとテンプレートにあるのでこれを参考にします。あとはThumbのDragDeltaイベントでDataGridColumnのWidthを増減すれば実現できます。

スタイルを調整する

ここまで出来たら後はスタイルを調整するだけなのですが、これもひと苦労します。まずは、上段と下段のヘッダーの横位置をピクセル単位で微調整できるようにDataGridColumnHeaderのスタイルをコントロールテンプレートで再定義します。また、今回左上のエリア(SelectAll用のボタン)についても背景色を変えたかったので設定しようと思ったのですが、これがどうも簡単には指定できないようで困りました。調べると
Styling hard-to-reach elements in control templates with attached behavioursに添付ビヘイビアを使ってこれを解決する方法がありました。今回以外でもコントロールの一部のスタイルを変えたい場合に利用できそうなテクニックです。
これでやっと完成です。

サンプルソースコード