C# DataGridView セルのマージ(疑似的結合)

今回は標準ヘッダーを利用せず1行目2行目をヘッダーとして利用しており、試しに1行目の1列目2列目を擬似的結合してみた。

どこのサイトもだいたい同じ説明をしていて、CellPainting()で処理するのが基本という感じ。ちょっとつまづいたのが標準描画(セルの背景色とか文字列とか)で疑似的結合のRetangleが隠れてしまう現象で、回避するためにはe.Handled = trueで標準描画をキャンセルする必要があった。

例えば今回は利用しないけど、標準描画の一部をキャンセルする場合、e.Paint()で標準描画を呼び、e.Handled = trueで終了させる。
var p = e.PaintParts & ~DataGridViewPaintParts.Border;
e.Paint(e.ClipBounds, p);
e.Handled = true;
これでBorderの描画がキャンセルされる。

***

次は擬似的結合の範囲をループで動的に取得してみた。1行目1~5列目までは罫線Bottomを消すだけで、それ以降の1行目6列目以降(年月の部分)を疑似的結合している。

描画セル(1行目6列目)が画面から消えない(見えなくなることがない)作りならこれで問題ないのだけど、横スクロールなどで描画セルが画面から消えると疑似的結合のRectangleも消えて黒塗りになってしまうという厄介な問題が発生する。

スクロールの状態から描画セルを修正するような計算をすれば回避できるかもしれないけど、かなり面倒だしCellPainting()は頻繁に呼ばれているので、あまり複雑な計算もしたくない。

***

ちなみに、CellPainting()ではなくPaint()で処理することもできる。イベント引数からCellBoundsを取れないので、直接DataGridViewで指定するだけ。

***

色々考えたけど、結局、Rectangleの擬似的結合は止めて、CellPainting()では罫線だけ処理した。Alignmentで中央にできないし長い文字列も設定できないが、描画落ちするよりはいいかなという感じ。

***

数日後追記。

しばらく経ってから思いついたのが画像を利用するアイデアで、疑似的結合のサイズで動的に画像を生成して、それぞれのセルのサイズで抜き出して描画するという方法。

これだと見た目は結合されているけど、描画はセルごとなので黒塗りになってしまう問題も発生しない。

ただこの方法の場合、疑似的結合の範囲やサイズが固定なら問題ないけど、範囲やサイズが動的に変化するような仕様だとかなり複雑になってしまう。