まずは見た目だけのセル結合です。ラベルのように表示するだけであれば、この方法で十分だと思います。
セルの描画部を処理するだけです。

上記図は、以下の4列のDataGridViewTextBoxColumnを追加し以下のコードでデータを挿入しています。
int num = 1; for (int i = 0; i < 10; i++) dataGridView1.Rows.Add(num++, num++, num++, num++);
これを基に、1列目(Column1)では2行を結合し1セルとします。次に1行おきに2列目、3列目を結合します。

結果このような感じになります。
以下のように「CellPainting」イベントを処理しています。
コードを見ていただければわかりますが大した事はしていません。シコシコと描画処理をしているだけです。
private void dataGridView1_CellPainting(object sender,
DataGridViewCellPaintingEventArgs e) {
DataGridView dv = (DataGridView)sender;
// 行・列共にヘッダは処理しない
if(e.RowIndex < 0 || e.ColumnIndex < 0)
return;
Rectangle rect;
DataGridViewCell cell;
// 1列目の処理
if(e.ColumnIndex == 0) {
rect = e.CellBounds;
// 奇数行(1,3,5..行目 = RowIndexは0,2,4..)
if(e.RowIndex % 2 == 0) {
cell = dataGridView1[e.ColumnIndex, e.RowIndex + 1];
//一つ下の次のセルの高さを足す
rect.Height += cell.Size.Height;
}
// 偶数行の処理
else {
cell = dataGridView1[e.ColumnIndex, e.RowIndex - 1];
// 一つ上のセルの高さを足し、矩形の座標も一つ上のセルに合わす
rect.Height += cell.Size.Height;
rect.Y -= cell.Size.Height;
}
// セルボーダーライン分矩形の位置を補正
rect.X -= 1;
rect.Y -= 1;
// 背景、セルボーダーライン、セルの値を描画
e.Graphics.FillRectangle(
new SolidBrush(e.CellStyle.BackColor), rect);
e.Graphics.DrawRectangle(
new Pen(dv.GridColor), rect);
TextRenderer.DrawText(e.Graphics,
cell.FormattedValue.ToString(),
e.CellStyle.Font, rect, e.CellStyle.ForeColor,
TextFormatFlags.HorizontalCenter
| TextFormatFlags.VerticalCenter);
// イベント ハンドラ内で処理を行ったことを通知
e.Handled = true;
}
// 2列目と3列目の結合処理
else if(e.ColumnIndex == 1) {
// 奇数行のみ列結合
if(e.RowIndex % 2 == 0) {
rect = e.CellBounds;
cell = dataGridView1[e.ColumnIndex + 1, e.RowIndex];
// 一つ右のセルの幅を足す
rect.Width += cell.Size.Width;
rect.X -= 1;
rect.Y -= 1;
e.Graphics.FillRectangle(
new SolidBrush(e.CellStyle.BackColor), rect);
e.Graphics.DrawRectangle(new Pen(dv.GridColor), rect);
TextRenderer.DrawText(e.Graphics,
e.FormattedValue.ToString(),
e.CellStyle.Font, rect, e.CellStyle.ForeColor,
TextFormatFlags.HorizontalCenter
| TextFormatFlags.VerticalCenter);
e.Handled = true;
} else {
// 2列目の偶数行は、結合を行わないので、通常の描画処理に任せる
e.Paint(e.ClipBounds, e.PaintParts);
}
} else {
// 3列目の奇数行は描画処理をせずに、
// イベントハンドラ内で処理を完了したこと通知
if(e.RowIndex % 2 == 0 && e.ColumnIndex == 2)
e.Handled = true;
}
}
正しくは、値の描画の処で「e.CellStyle.Alignment」を確認すべきですが、ここでは簡単にするためにセンターに描画しています。
他に、セルをReadOnlyにする処理や、結合セルのフォーカスがある場合の描画処理、キー入力でのフォーカスの移動の処理が必要です。
上記、未実装の部分は別の日に考えます。あしからず...
セルの結合参考にさせて頂きました。
返信削除描画しないでe.handle=trueにする箇所はちょこちょこ再描画しないと乱れますね。ですが実装できたので良かったです。
ありがとうございました。
datagridviewのスクロールを偶数間隔にするときれいに描画できました
返信削除