トップ回答者
コンボボックス未選択でデータグリッドビューに空行が表示されてしまいます。

質問
-
いつもお世話になっております。Vs2010 C# Pro + Windows7 Pro + PostgreSQLで開発してます。
リレーションで連動させている2つのコンボボックスで絞り込んだデータを外部キーにしたDBからのデータをデータグリッドビューに表示させていますがForm_Load状態で(コンボボックスはまだ選択していない状態)データグリッドビューに空のレコードが一行表示されてしまいます。左側に三角印の空白状態のレコードです。米印の新規入力行とは別にという意味です。コンボボックスを選択して表示されたデータは一番下に新規入力行があり、正常に表示できています。なぜこのような状態になるのか、改善策どなたか教えてください。
// リレーション作成ds.Relations.Add(new DataRelation("rel_ns",ds.Tables["numbers"].Columns["n_id"],ds.Tables["sector"].Columns["n_id"]));
cmb_n_id.DataSource = ds;cmb_n_id.DisplayMember = "numbers.number";cmb_n_id.ValueMember = "numbers.n_id";
cmb_s_id.DataSource = ds;cmb_s_id.DisplayMember = "numbers.rel_ns.sector";cmb_s_id.ValueMember = "numbers.rel_ns.s_id";cmb_s_id.SelectedIndexChanged += new EventHandler(cmb_s_id_SelectedIndexChanged);
// bindingSourceRecordsを設定bindingSourceRecords.DataSource = ds;bindingSourceRecords.DataMember = "records";
bindingNavigatorRecords.BindingSource = bindingSourceRecords;dataGridViewRecords.AutoGenerateColumns = false;dataGridViewRecords.DataSource = bindingSourceRecords;
回答
すべての返信
-
-
trapemiyaさん、いつもありがとうございます。
どうしてこうなるのかは私には説明できないのですが
// before
bindingNavigatorRecords.BindingSource = bindingSourceRecords;
dataGridViewRecords.AutoGenerateColumns = false;
dataGridViewRecords.DataSource = bindingSourceRecords;
// after
bindingNavigatorRecords.BindingSource = bindingSourceRecords;
dataGridViewRecords.AutoGenerateColumns = false;
dataGridViewRecords.DataSource = ds;
データグリッドビューのデータソースをバインディングソースにしていたからのようです。
データグリッドビューのデータソースをデータセットにすることで解決できました。
bindingSourceRecords.DataSource = ds;
根本は同じdsをデータソースにしていてもこのような動作になるのですね。
-
どうしてこうなるのかは私には説明できないのですが
おかしいですね? 私にも説明できず、疑問に思いましたので私の方でコードを想像しながらテストしてみましたが、BindingSourceでも問題なく実行されました。
dsの場合も同様に実行されましたが、DataMemberでテーブル名を新たに指定する必要がありました。基本的にはBindingSourceでも問題ありませんので、何かが影響しているのだと思います。
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/ -
朴智星さん、ありがとうございます。Form_Loadでは、以下のように設定しています。こうではなくて、具体的に値を設定することが必要なのでしょうか?
da.SelectCommand = new NpgsqlCommand("select"+ " r_id"+ ", id"+ ", s_id"+ ", results"+ ", flg"+ ", time_stamp"+ ", n_id"+ " from"+ " records"+ " where n_id=:n_id"+ " and s_id=:s_id"+ " order by r_id",m_conn);if (cmb_n_id.SelectedItem == null){// SelectedItemがない場合da.SelectCommand.Parameters.Add(new NpgsqlParameter("n_id",NpgsqlTypes.NpgsqlDbType.Integer, 0, "n_id",ParameterDirection.Input, false, 0, 0, DataRowVersion.Current,DBNull.Value));}else{// SelecteItemがある場合DataRowView row = (DataRowView)cmb_n_id.SelectedItem;da.SelectCommand.Parameters.AddWithValue("n_id", row["n_id"]);}if (cmb_s_id.SelectedItem == null){// SelectedItemがない場合da.SelectCommand.Parameters.Add(new NpgsqlParameter("s_id",NpgsqlTypes.NpgsqlDbType.Integer, 0, "s_id",ParameterDirection.Input, false, 0, 0, DataRowVersion.Current,DBNull.Value));}else{// SelecteItemがある場合DataRowView row = (DataRowView)cmb_s_id.SelectedItem;da.SelectCommand.Parameters.AddWithValue("s_id", row["s_id"]);}
>対策としては、DataGridViewをはじめはVisible = falseなどにして、コンボボックスが選択された状態でVisible = trueにするなどいかがでしょう。
>もしくはdataSource = nullなど。
これは、まだ試していないのでやってみようと思います。
-
DataGridViewを描画するタイミングがポイントになると思います。
上記の分岐につきましては、コンボボックスが2つともに選択された状態である場合にのみ描画するの条件がいいと思います。
また、コンボボックスにつきましては、コンストラクタで設定してselectedIndexを1などに指定しておけば、常に選択されている状態になります。
その場合は、上記の分岐が必要なくなります。(選択項目にnullを入れた場合はその限りではありませんが)
考慮事項といたしましては、n_id,s_idがnullという条件が実際のrecordsテーブルに存在するか、です。
あと、気になった点では、コンボボックスの片方にだけSelectedIndexChangeイベントがあるというところでしょうか。
両方入れて、双方でDataGridViewを描画するメソッドを呼ぶようにしてあげたらいいのか、と。