この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
DataGridViewコントロールでは、同じ内容のセルが連続して並ぶ場合に、それらを1つのセルにまとめることにより表示を見やすくできる。以下の画面は通常の表示(上)と同じセルを1つにまとめた場合の表示(下)の例である。
このような表示は、不要なセルの値と境界線を消すことにより実現できる。本稿では、次のような手順によりこれを実装している。
1.のセルの値を書き換える処理は、セルが表示される直前にセルごとに発生するCellFormattingイベントのタイミングで行うことができる。また、2.と3.のセルの境界線の描画設定については、セルの描画時にセルごとに発生するCellPaintingイベントのタイミングで行える。どちらのイベントにおいても、イベント・ハンドラに渡されるパラメータから、現在処理中のセルの位置を知ることができる。
まず以下に、これらの手順を実装したサンプル・プログラムを示す。上記の画面はそのサンプル・プログラムの実行例である。
このサンプル・プログラムでは、DataGridViewコントロールに表示するデータとして、@ITの新着記事についてのRSS情報(RSS 2.0)を使用している。プログラムでは、このRSS情報から、記事の公開日、公開しているフォーラム、記事タイトルのみをグリッドに表示する。RSS情報の取得とDataGridViewコントロールの初期化は、フォームのLoadイベント・ハンドラで行っている。
// dgvgroupedcell.cs
using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
public class MyForm : Form {
DataGridView dgv;
// 指定したセルと1つ上のセルの値を比較
bool IsTheSameCellValue(int column, int row) {
DataGridViewCell cell1 = dgv[column, row];
DataGridViewCell cell2 = dgv[column, row - 1];
if (cell1.Value == null || cell2.Value == null) {
return false;
}
// ここでは文字列としてセルの値を比較
if (cell1.Value.ToString() == cell2.Value.ToString()) {
return true;
} else {
return false;
}
}
// DataGridViewのCellFormattingイベント・ハンドラ
void dgv_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) {
// 1行目については何もしない
if (e.RowIndex == 0)
return;
if (IsTheSameCellValue(e.ColumnIndex, e.RowIndex)) {
e.Value = "";
e.FormattingApplied = true; // 以降の書式設定は不要
}
}
// DataGridViewのCellPaintingイベント・ハンドラ
void dgv_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) {
// セルの下側の境界線を「境界線なし」に設定
e.AdvancedBorderStyle.Bottom = DataGridViewAdvancedCellBorderStyle.None; (1)
// 1行目や列ヘッダ、行ヘッダの場合は何もしない
if (e.RowIndex < 1 || e.ColumnIndex < 0)
return;
if (IsTheSameCellValue(e.ColumnIndex, e.RowIndex)) {
// セルの上側の境界線を「境界線なし」に設定
e.AdvancedBorderStyle.Top = DataGridViewAdvancedCellBorderStyle.None; (2)
} else {
// セルの上側の境界線を既定の境界線に設定
e.AdvancedBorderStyle.Top = dgv.AdvancedCellBorderStyle.Top; (3)
}
}
// フォームのLoadイベント・ハンドラ
void MyForm_Load(object sender, EventArgs e) {
// @ITのRSS情報をデータセットに読み込む
DataSet ds = new DataSet();
ds.ReadXml("http://atmarkit.itmedia.co.jp/rss/rss.xml");
// 3つの列(公開日、フォーラム、タイトル)のみを表示
dgv.ColumnCount = 3;
dgv.Columns[0].DataPropertyName = "pubDate";
dgv.Columns[0].HeaderText = "公開日";
dgv.Columns[1].DataPropertyName = "category";
dgv.Columns[1].HeaderText = "フォーラム";
dgv.Columns[2].DataPropertyName = "title";
dgv.Columns[2].HeaderText = "記事タイトル";
// 列の自動生成を行わない
dgv.AutoGenerateColumns = false;
// RSS内の<item>要素部分をデータソースとして使用
dgv.DataSource = ds.Tables["item"];
}
// フォームのコンストラクタ
public MyForm() {
dgv = new DataGridView();
dgv.Dock = DockStyle.Fill;
dgv.CellFormatting += new DataGridViewCellFormattingEventHandler(dgv_CellFormatting);
dgv.CellPainting += new DataGridViewCellPaintingEventHandler(dgv_CellPainting);
this.Controls.Add(dgv);
this.Size = new Size(480, 240);
this.Load += new EventHandler(MyForm_Load);
}
}
class Program {
[STAThread]
static void Main() {
Application.Run(new MyForm());
}
}
// コンパイル方法:csc dgvgroupedcell.cs
Copyright© Digital Advantage Corp. All Rights Reserved.