DataGridView(03)
目的
VisualStudio 2019 上の C#言語と .Net Framework を用いて、データを定義したり、操作したり、画面上に表示したりというようなことについて、さまざまな角度から説明します。
基本的に、「このとおりにやれば、確実に、プログラムは動く」というものを目指しています。
今回の目的は、「前回の問題点の修正と、【一行増やすボタン】の追加」です。
準備
前回までのソース・コードは、次のとおりです。
using System.Data;
using System.Drawing;
using System.Windows.Forms;
namespace DGV02
{
public partial class Form1 : Form
{
DataTable dt; // 元のデータ
DataGridView dgv; // 実際に表示するもの
Label L1,L2; // 表示用ラベル
private void dgv_Enter()
{
int x = dgv.CurrentCellAddress.X;
int y = dgv.CurrentCellAddress.Y;
L1.Text = "座標 (" + x.ToString() + "," + y.ToString() + ")";
L2.Text = "内容 (" + dt.Rows[y][x] + ")";
}
public Form1()
{
InitializeComponent();
// アプリケーション全体
this.Text = "データグリッドビュー DGV02"; // アプリケーションのタイトル
this.Size = new Size(1400, 850); // アプリケーション全体の大きさ
StartPosition = FormStartPosition.Manual; // 起動時の位置を設定する
DesktopLocation = new Point(20, 20); // 起動時の位置
// データ作成
dt = new DataTable();
dt.Columns.Add("番号");
dt.Columns.Add("氏名");
dt.Columns.Add("点数");
for (int i = 0; i < 10; i++)
{
DataRow dr = dt.NewRow();
dt.Rows.Add(dr);
}
// データグリッドビュー
dgv = new DataGridView();
dgv.Size = new Size(1340, 740); // 表の大きさ
dgv.Location = new Point(20, 50); // 表の位置
dgv.DataSource = dt; // データとデータグリッドビューを接続
this.Controls.Add(dgv); // 画面に表示
dgv.CellEnter += (s,e) => dgv_Enter();
// 「現在の自分の位置を示すラベル」の設定
L1 = new Label(); // ラベルをつくる
L1.Location = new Point(20, 5); // ラベルの位置
L1.Size = new Size(200, 40); // ラベルのサイズ
L1.BackColor = Color.LightPink; // ラベルの背景色
L1.Text = "座標 L1"; // ラベルに表示する文字
L1.Font = new Font("メイリオ", 18); // ラベルの文字種や大きさ
L1.TextAlign = ContentAlignment.MiddleCenter; // 文字をラベルの中心に表示する
this.Controls.Add(L1); // ラベルを表示させる
// 「現在地のセルの内容を示すラベル」の設定
L2 = new Label(); // ラベルをつくる
L2.Location = new Point(240, 5); // ラベルの位置
L2.Size = new Size(200, 40); // ラベルのサイズ
L2.BackColor = Color.LightCyan; // ラベルの背景色
L2.Text = "内容 L2"; // ラベルに表示する文字
L2.Font = new Font("メイリオ", 18); // ラベルの文字種や大きさ
L2.TextAlign = ContentAlignment.MiddleCenter; // 文字をラベルの中心に表示する
this.Controls.Add(L2); // ラベルを表示させる
}
}
}
これを実際に動かすと、1行目から10行目までは正常に動きますが、11行目に移動しようとすると、「データが存在しない」というエラーが発生します。実際にエラーが発生している動画は、次のとおりです。
また、エラー・メッセージは、次のとおりです。
原因はどこにあるのか
データ・テーブル「dt」は、10行しかありません。しかし、データ・グリッド・ビュー「dgv」は11行あります。
現在は、10行目にカーソルがありますが、ここからさらに、ひとつ下の行に移動しようとすると、「行がありません」というエラーが発生します。
一番下の「追加の行」を非表示にする
そこで、一番下の行を表示させないように設定します。すなわち、
dgv.AllowUserToAddRows = false;
を付け加えます。
こうすると、一番下の「追加の行」が表示されなります。
一行増やしたいときはどうするか
そこで、「現在、自分が居る行の下に、新しい行を追加する」というコマンドを実現するようなボタンを追加します。
Button B1; // 一行増やすためのボタン
// 「一行増やすためのボタン」の設定
B1 = new Button(); // ラベルをつくる
B1.Location = new Point(460, 5); // ラベルの位置
B1.Size = new Size(200, 40); // ラベルのサイズ
B1.BackColor = Color.Yellow; // ラベルの背景色
B1.Text = "一行追加"; // ラベルに表示する文字
B1.Font = new Font("メイリオ", 18); // ラベルの文字種や大きさ
B1.TextAlign = ContentAlignment.MiddleCenter; // 文字をラベルの中心に表示する
this.Controls.Add(B1); // ラベルを表示させる
この状態で、画面は次のようになります。
ただし、このボタンには、関数が結びつけられていませんから、ボタンを押しても何も起こりません。
一行増やす関数
自分のカーソルの現在位置を得るためには、つぎのようにします。
int x = dgv.CurrentCellAddress.X;
int y = dgv.CurrentCellAddress.Y;
また、現在のデータベースから「新しい一行」をつくるには、つぎのようにします。
DataRow dr = dt.NewRow();
「dr」が、新しい一行を表しています。この「新しい一行」を、現在位置の次のところに挿入し、カーソルをその場所に移動させます。
dt.Rows.InsertAt(dr, y+1);
dgv.CurrentCell = dgv[x, y+1];
関数全体は、次のようになります。
ボタンを押したときに、関数を呼び出すためには、次のようにします。
B1.Click += (s, e) => NewLine(); // 一行増やす関数を呼び出す
前後と一緒に表示すると、次のようになります。
動画で動作を確認する
以上の様子を動画で表示させると次のようになります。
ソースファイル
今回のプログラム全体のソースファイルは、次のとおりです。
using System.Data;
using System.Drawing;
using System.Windows.Forms;
namespace DGV03
{
// 一番下の行に移動すると、
// 表データがないと言われてエラーが出る。
// これをどのように回避するか
public partial class Form1 : Form
{
DataTable dt; // 元のデータ
DataGridView dgv; // 実際に表示するもの
Label L1, L2; // 表示用ラベル
Button B1; // 一行増やすためのボタン
private void NewLine()
{
int x = dgv.CurrentCellAddress.X;
int y = dgv.CurrentCellAddress.Y;
DataRow dr = dt.NewRow();
dt.Rows.InsertAt(dr, y+1);
dgv.CurrentCell = dgv[x, y+1];
}
private void dgv_Enter()
{
int x = dgv.CurrentCellAddress.X;
int y = dgv.CurrentCellAddress.Y;
L1.Text = "座標 (" + x.ToString() + "," + y.ToString() + ")";
L2.Text = "内容 (" + dt.Rows[y][x] + ")";
}
public Form1()
{
InitializeComponent();
// アプリケーション全体
this.Text = "データグリッドビュー DGV03"; // アプリケーションのタイトル
this.Size = new Size(1400, 850); // アプリケーション全体の大きさ
StartPosition = FormStartPosition.Manual; // 起動時の位置を設定する
DesktopLocation = new Point(20, 20); // 起動時の位置
// データ作成
dt = new DataTable();
dt.Columns.Add("番号");
dt.Columns.Add("氏名");
dt.Columns.Add("点数");
for (int i = 0; i < 10; i++)
{
DataRow dr = dt.NewRow();
dt.Rows.Add(dr);
}
// データグリッドビュー
dgv = new DataGridView();
dgv.Size = new Size(1340, 740); // 表の大きさ
dgv.Location = new Point(20, 50); // 表の位置
dgv.AllowUserToAddRows = false; // 一番下の追加の行を見せない
dgv.DataSource = dt; // データとデータグリッドビューを接続
this.Controls.Add(dgv); // 画面に表示
dgv.CellEnter += (s, e) => dgv_Enter();
// 「現在の自分の位置を示すラベル」の設定
L1 = new Label(); // ラベルをつくる
L1.Location = new Point(20, 5); // ラベルの位置
L1.Size = new Size(200, 40); // ラベルのサイズ
L1.BackColor = Color.LightPink; // ラベルの背景色
L1.Text = "座標 L1"; // ラベルに表示する文字
L1.Font = new Font("メイリオ", 18); // ラベルの文字種や大きさ
L1.TextAlign = ContentAlignment.MiddleCenter; // 文字をラベルの中心に表示する
this.Controls.Add(L1); // ラベルを表示させる
// 「現在地のセルの内容を示すラベル」の設定
L2 = new Label(); // ラベルをつくる
L2.Location = new Point(240, 5); // ラベルの位置
L2.Size = new Size(200, 40); // ラベルのサイズ
L2.BackColor = Color.LightCyan; // ラベルの背景色
L2.Text = "内容 L2"; // ラベルに表示する文字
L2.Font = new Font("メイリオ", 18); // ラベルの文字種や大きさ
L2.TextAlign = ContentAlignment.MiddleCenter; // 文字をラベルの中心に表示する
this.Controls.Add(L2); // ラベルを表示させる
// 「一行増やすためのボタン」の設定
B1 = new Button(); // ラベルをつくる
B1.Location = new Point(460, 5); // ラベルの位置
B1.Size = new Size(200, 40); // ラベルのサイズ
B1.BackColor = Color.Yellow; // ラベルの背景色
B1.Text = "一行追加"; // ラベルに表示する文字
B1.Font = new Font("メイリオ", 18); // ラベルの文字種や大きさ
B1.TextAlign = ContentAlignment.MiddleCenter; // 文字をラベルの中心に表示する
B1.Click += (s, e) => NewLine(); // 一行増やす関数を呼び出す
this.Controls.Add(B1); // ラベルを表示させる
}
}
}
参考(リンク集)
他のページへのリンクをすべて書いていると、それぞれのページでの更新がとても大変になるので、一括してリンクページで管理します。
⇒ DataGridView に関するページのリンク集