まずは見た目だけのセル結合です。ラベルのように表示するだけであれば、この方法で十分だと思います。
セルの描画部を処理するだけです。
上記図は、以下の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のスクロールを偶数間隔にするときれいに描画できました
返信削除