DOBON.NET DOBON.NETプログラミング掲示板過去ログ

DataGridViewで列数が倍になります

環境/言語:[WindowsXP]
分類:[.NET]

こんにちは。C#のDataGridViewで思ったようにデータ表示されずに悩んでいます。

データベースに用意されているデータは下記になります。
・テーブル名:TABLE
・フィールド:ID、Quantity
・フィールドデータ:ZZZ,5

Form1にはデータグリッドビュー(dgv)と検索ボタン(cmdSearch)が配置されています。
検索ボタンをクリックすると、データベースの値を取得して、dgvに表示されます。

検索ボタンをクリックすると、下記のようにデータが表示されてしまいます。
列名が違うのは、フォームロード時に列名を変更している為です。

ID,Quantity,アイディー,数量
ZZZ,5,ZZZ,5

問題:
なぜ、4列になってしまうのかがわかりません。これを防ぐにはどのように解決したらよろしいでしょうか?
下記がコードになります。宜しくお願い致します。

//////////////////////////////////////////////////////////
//フォームのロード
//////////////////////////////////////////////////////////
private void Form1Load(object sender, EventArgs e)
{
dt = new DataTable();
adp = new DataAdapter("SELECT * FROM TABLE", Conn);
adp.Fill(dt);

//グリッドにDataTableの中身を表示
this.dgv.DataSource = dt;

//プライマリーキー設定
dt.PrimaryKey = new DataColumn[] { dt.Columns["ID"] };

//列名変更
dt.Columns[0].ColumnName = "アイディー";
dt.Columns[1].ColumnName = "数量";

adp.Dispose();
dt.Dispose();
}

//フォームロード時にdgvにデータを表示させています。dgvには下記のように表示されます。
//アイディー,数量
//ZZZ,5

//////////////////////////////////////////////////////////
//検索ボタン押下時
//////////////////////////////////////////////////////////
private void cmdSearch_Click(object sender, EventArgs e)
{
dt.Clear();
dt.Rows.Clear();

adp = new DataAdapter("SELECT * FROM TABLE ", Conn);
adp.Fill(dt);
this.dgv.DataSource = dt;

adp.Dispose();
dt.Dispose();
}

//検索ボタン押下時にdgvにデータを表示させています。dgvには下記のように表示されます。
//ID,Quantity,アイディー,数量
//ZZZ,5,ZZZ,5

クイックウォッチでdtの中身を確認しましたが、フォームロード時に列名を変更しなければ、4列になることはありませんでした。
ただ、列名は変更したいです。ご助言のほど宜しくお願い致します。
■No31961に返信(高木さんの記事)
> これを防ぐにはどのように解決したらよろしいでしょうか?
DataGridView の AutoGenerateColumns が true のままの場合、
DataSource を割り当てた時点で、自動的に列が生成されます。


具体例が、ここのサイト(DOBON.NET)の Tips 集にあります。
http://dobon.net/vb/dotnet/datagridview/addcolumn.html
■No31961に返信(高木さんの記事)
> this.dgv.DataSource = dt;
> dt.Dispose();

今回は相手が DataTable だったので問題は起きていませんが、
他で使われている最中のオブジェクトを Dispose するのは御法度ですよ。
魔界の仮面弁士さん

> 今回は相手が DataTable だったので問題は起きていませんが、
> 他で使われている最中のオブジェクトを Dispose するのは御法度ですよ。

⇒こちら知りませんでした。アドバイスありがとうございました。

お教え頂いたとURLで下記のコードで1列追加できました。

DataGridViewTextBoxColumn textColumn = new DataGridViewTextBoxColumn;
textColumn.DataPropertyName = "ID";
textColumn.Name = "ID";
textColumn.HeaderText = "アイディー";
this.dgv.Columns.Add(textColumn);

ただ、複数列追加したかったので、配列を使おうとしました。そうしましたら、参照エラーが発生しました。

DataGridViewTextBoxColumn[] textColumn = new DataGridViewTextBoxColumn[2];
//nullreferenceexception オブジェクト参照がオブジェクト
//インスタンスに設定されていません。
textColumn[0].DataPropertyName = "ID";

配列にこだわっているわけではないのですが、複数列を追加したい場合、どのようにすればよいでしょうか?お手数おかけして申し訳ありません。
2013/12/03(Tue) 16:30:39 編集(投稿者)

■No31964に返信(高木さんの記事)
> ただ、複数列追加したかったので、
.Columns.Add を複数回呼び出すか、もしくは
.Columns.AddRange を使えば良いかと。


> お教え頂いたとURLで下記のコードで1列追加できました。
> DataGridViewTextBoxColumn textColumn = new DataGridViewTextBoxColumn;
これ、文法エラーになりませんか?


> DataGridViewTextBoxColumn[] textColumn = new DataGridViewTextBoxColumn[2];
これにより、textColumn[0] と textColumn[1] という 2 つの器が
出来上がりますが、それぞれの器の中身は空っぽ(null)の状態です。
なので、
 textColumn[0] = new DataGridViewTextBoxColumn();
などのコードが無いことには、先のエラーが引き起こされることとなります。


int[] a = new int[2]; // これだと、a[0] も a[1] も初期値(=0)です。
a[1] = 99; // これにより、a[1] に Int32 な値がセットされます。
int[] b = new int[] { 11, 22 }; // これだと、b[0]=11;、b[1]=22; です。


> //nullreferenceexception オブジェクト参照がオブジェクト
nullreferenceexception ではなく
NullReferenceException ですね。

> textColumn[0].DataPropertyName = "ID";
textColumn[0] という器はできたものの、中身が null なので、
DataPropertyName プロパティにアクセスすることができない状態です。


> 配列にこだわっているわけではないのですが、
> 複数列を追加したい場合、どのようにすればよいでしょうか?
.ColumnCount を指定した後で .Columns[n] を個別にセットするか、または

 col = new DataGridViewTextBoxColumn();
 col.DataPropertyName = 連携する列名1;
 dataGridView1.Columns.Add(col);

 col = new DataGridViewTextBoxColumn();
 col.DataPropertyName = 連携する列名2;
 dataGridView1.Columns.Add(col);

のように、必要な回数だけ繰り返し実行すれば OK です。

上記では、同じ変数 col を使いまわして登録していますが、
別々の変数を使ってもよいですし(デザイナ画面で作った場合はそうなる)、
配列等で管理しても良いでしょう。

列名(.Name)やタイトル(.HeaderText)の変更はお好みで。
別の型(DataGridViewCheckBoxColumn など)を混ぜても構いません。
2013/12/03(Tue) 20:46:20 編集(投稿者)

魔界の仮面弁士さん

詳細なご解説ありがとうございます。大変参考になりました。ありがとうございます。

> ×DataGridViewTextBoxColumn textColumn = new DataGridViewTextBoxColumn;
> ○DataGridViewTextBoxColumn textColumn = new DataGridViewTextBoxColumn();
>これ、文法エラーになりませんか?

⇒おっしゃるように、文法エラーになりました・・・
また配列の意味もしっかり理解していませんでした。再度、独習C#を読んで勉強致します。

お教え頂きました事を参考にさせて頂き、下記のようなコードで目的が実現できました。

//列が自動的に作成されないようにする
this.dgv.AutoGenerateColumns = false;

//データグリッドにDataTableをバインド
this.dgv.DataSource = dt;

//DataGridView に表示される列の数を取得または設定します。
int col = this.dt.Columns.Count;

//DataGridViewTextBoxColumn列を作成する
DataGridViewTextBoxColumn[] textColumn = new DataGridViewTextBoxColumn[col];

//DataGridViewTextBoxColumn 初期化
for(int count = 0;count < col;count++)
textColumn[count] = new DataGridViewTextBoxColumn();

textColumn[0].DataPropertyName = "ID";
textColumn[1].DataPropertyName = "Quantity";

//ヘッダーを設定する 列のヘッダー セルのキャプション テキストを取得または設定します。
textColumn[0].HeaderText = "アイディー";
textColumn[1].HeaderText = "数量";

//列を追加する
for (int count = 0; count < col; count++)
this.dgv.Columns.Add(textColumn[count]);

目的が達成できて嬉しいです。ありがとうございました!
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板