Windows Formsアプリケーションで DataGridView を使用する際、デフォルトではフッター行が提供されていません。しかし、合計行や特定の情報を表示するためにフッターを追加したい場合があります。この記事では、DataGridView にカスタムフッターを追加し、列幅の同期や水平スクロールを実装する方法を解説します。
実装の特徴
- 列幅の同期:メインのDataGridView とフッターの列幅を同期
- 水平スクロールの同期: メインのDataGridView とフッターの水平スクロールを連動
- フッターの固定表示:垂直スクロール時にフッターが常に下部に表示される
- メインのDataGridViewの設定 DataGridViewの設定は、SetupDataGridViewメソッドでは、以下のような設定を行います。
- カスタムフッターの実装
- 列幅の同期
- 水平スクロールの同期
- フッターの位置調整
- 合計行の計算
- サンプルデータの追加
private void InitializeDataGridView()
{
dt = new DataTable();
// Create columns
dt.Columns.Add("項目", typeof(string));
dt.Columns.Add("数量", typeof(int));
dt.Columns.Add("価格", typeof(decimal));
dt.Columns.Add("合計", typeof(decimal));
dataGridView1.DataSource = dt;
dataGridView1.Columns["項目"].Width = 100;
dataGridView1.Columns["数量"].Width = 100;
dataGridView1.Columns["価格"].Width = 100;
dataGridView1.Columns["合計"].Width = 100;
// Configure DataGridView
//dataGridView1.AllowUserToAddRows = false;
dataGridView1.BorderStyle = BorderStyle.None;
dataGridView1.RowHeadersVisible = false;
//dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
dataGridViewFooter.SendToBack();
dataGridView1.Columns["項目"].ReadOnly = true;
dataGridView1.Columns["合計"].ReadOnly = true;
// Set up events
// DataGridViewのScrollイベントに紐付け
dataGridView1.Scroll += (s, e) => SyncFooterScroll();
dataGridView1.ColumnWidthChanged += (s, e) => SyncFooterColumns(); // Sync column widths
dataGridView1.CellValueChanged += DataGridView1_CellValueChanged; // Handle cell value changes
this.Load += MainForm_Load;
}
フッターとして機能する別の DataGridView を追加します。このフッターは、メインの DataGridView の下部に固定され、列幅やスクロールが同期されます。フッターの DataGridView を初期化し、メインの DataGridView と同期させます。
private void InitializeFooter()
{
// フッターの設定
dataGridViewFooter.AllowUserToAddRows = false;
dataGridViewFooter.AllowUserToResizeRows = false;
dataGridViewFooter.RowHeadersVisible = false;
dataGridViewFooter.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
dataGridViewFooter.BackgroundColor = SystemColors.Control;
dataGridViewFooter.BorderStyle = BorderStyle.None;
dataGridViewFooter.Height = 25; // フッターの高さ
dataGridViewFooter.ReadOnly = true;
dataGridViewFooter.DefaultCellStyle.Font = new Font(dataGridView1.Font, FontStyle.Bold);
dataGridViewFooter.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
// フォームにフッターを追加
this.Controls.Add(dataGridViewFooter);
this.Controls.SetChildIndex(dataGridViewFooter, 0); // フッターを前面に表示
// 列の同期
SyncFooterColumns();
// フッターの位置を更新
UpdateFooterPosition();
}
メインの DataGridView とフッターの列幅を同期するために、SyncFooterColumns メソッドを実装します.
private void SyncFooterColumns()
{
// 既存の列をクリア
dataGridViewFooter.Columns.Clear();
// メインのDataGridViewの列をフッターに追加
foreach (DataGridViewColumn column in dataGridView1.Columns)
{
var footerColumn = new DataGridViewTextBoxColumn
{
Name = column.Name,
HeaderText = column.HeaderText,
Width = column.Width,
ReadOnly = true,
SortMode = DataGridViewColumnSortMode.NotSortable
};
dataGridViewFooter.Columns.Add(footerColumn);
}
}
メインの DataGridView とフッターの水平スクロールを同期するために、SyncFooterScroll メソッドを実装します。
private void SyncFooterScroll()
{
// メインのDataGridViewとフッターの水平スクロールを同期
dataGridViewFooter.HorizontalScrollingOffset = dataGridView1.HorizontalScrollingOffset;
}
垂直スクロール時にフッターが常に下部に表示されるように、UpdateFooterPosition メソッドを実装します。
private void UpdateFooterPosition()
{
// フッターの位置をメインのDataGridViewの下部に設定
dataGridViewFooter.Top = dataGridView1.Bottom - 40; // 位置を調整
dataGridViewFooter.Left = dataGridView1.Left;
dataGridViewFooter.Width = dataGridView1.Width - SystemInformation.VerticalScrollBarWidth; // 垂直スクロールバーの幅を考慮
}
フッターに合計行を表示するために、CalculateTotals メソッドを実装します。
private void CalculateTotals()
{
decimal quantitySum = 0;
decimal priceSum = 0;
decimal totalSum = 0;
foreach (DataRow row in dt.Rows)
{
quantitySum += Convert.ToDecimal(row["数量"]);
priceSum += Convert.ToDecimal(row["価格"]);
row["合計"] = Convert.ToDecimal(row["数量"]) * Convert.ToDecimal(row["価格"]);
totalSum += Convert.ToDecimal(row["合計"]);
}
// フッターのヘッダーテキストを更新
dataGridViewFooter.Columns["項目"].HeaderText = "合計";
dataGridViewFooter.Columns["数量"].HeaderText = quantitySum.ToString();
dataGridViewFooter.Columns["価格"].HeaderText = priceSum.ToString("C", CultureInfo.GetCultureInfo("ja-JP"));
dataGridViewFooter.Columns["合計"].HeaderText = totalSum.ToString("C", CultureInfo.GetCultureInfo("ja-JP"));
}
フォームのロード時にサンプルデータを追加します。
private void MainForm_Load(object sender, EventArgs e)
{
// サンプルデータを追加
dt.Rows.Add("ブラックコーヒー", 3, 125.50m);
dt.Rows.Add("ミルクコーヒー", 2, 155.00m);
dt.Rows.Add("カフェオレ", 5, 175.05m);
// 合計を計算
CalculateTotals();
};
実行結果
- メインの DataGridView とフッターの列幅が同期されます。
- 水平スクロールが連動します。
- 垂直スクロール時にフッターが常に下部に表示されます。
まとめ
DataGridView にカスタムフッターを追加し、列幅の同期や水平スクロールを実装する方法を解説しました。このテクニックを使用することで、より柔軟でユーザーフレンドリーなデータ表示が可能になります。