トップ回答者
DataGridViewが空の時bindingNavigatorの削除を実行すると「現在の項目がないため、一覧から現在の項目を削除できません」

質問
-
いつもありがとうございます。非常に助かっています。
さて、また、DataGridView関係ですが、
DataGridViewが空の時bindingNavigatorの削除を実行すると
「現在の項目がないため、一覧から現在の項目を削除できません」の下記Exceptionが発生します。
System.InvalidOperationException はハンドルされませんでした。
Message=現在の項目がないため、一覧から現在の項目を削除できません。
Source=System.Windows.Forms
StackTrace:
再現手順
MS-ACCESSの簡単なmdbファイル(中身空っぽ)からデータセット、ドラッグアンドドロップでDataGridViewを貼りつけます。
BindingNavigatorもフォーム上に自動で生成されます。これだけです。全くコーディングしていない状態です。
この状態でいきなり「削除」ボタンを押下すると上記Exceptionが発生します。
DeleteItemのClickイベントの前にExceptionが発生しているようです。
(ブレークポイントをセットしても止まる前にExceptionが発生しています)
どうにかしてExceptionを抑止あるいはハンドルして継続させたいのですが、
どのように対処するのがいいでしょうか?お教えください。
開発環境:
Visual Studio 2010 Professional
開発言語:
C# 2010
回答
-
そもそもBindingNavigatorは削除確認が出ないので、以下を参考にして削除確認を出した方が良いでしょう。
Visual Studio 2005のフォームにおけるBindingNavigatorの拡張
http://internetcom.jp/developer/20060627/26.htmlこの削除確認のロジックでチェックし、削除対象の行が無ければ、そのようなメッセージを出せば良いように思います。
★良い回答には回答済みマークを付けよう! MVP - .NET http://d.hatena.ne.jp/trapemiya/
-
BindingNavigator が bindingNavigatorDeleteItem をコントロールしているらしく、たとえば Form1_Load メソッドで BindingSource.Count の値をしらべてゼロのとき Enabled を false にしても true に戻ってしまいます。
なので bindingNavigatorDeleteItem を BindingNavigator のコントロール下から外してから Enabled を false にしないとダメなようです。
しかし、コントロール下から外すと削除が効かなくなってしまうので、自力でコードを書いて bindingNavigatorDeleteItem のクリックイベントで削除できるようにしてやる必要があります。
Enabled を true に戻す処置も必要になります。それは bindingNavigatorAddNewItem のクリックイベントでやるのがよさそうです。
具体的には:
(1) Visual Studio の Formx.cs [デザイン] 画面で BindingNavigator のプロパティを表示して、その中の AddNewItem と DeleteItem を (なし) に設定する。(Formx.Designer.cd のコードでは null になります・・・が、そちらを修正しないこと)
(2) 既存の Form_Load メソッドに以下のようなコードを追加する。xXXBindingSource は自分のコードに合わせて修正してください。
int count = this.xXXBindingSource.Count; if (count == 0) { this.bindingNavigatorDeleteItem.Enabled = false; }
(3) bindingNavigatorDeleteItem と bindingNavigatorAddNewItem の Click イベントのハンドラを作る。
(4) 上記 (3) で作ったハンドラに以下のようなコードを追加する。xXXBindingSource, xXXDataGridView は自分のコードに合わせて修正してください。
private void bindingNavigatorDeleteItem_Click(object sender, EventArgs e) { this.xXXBindingSource.RemoveCurrent(); int count = this.xXXDataGridView.Rows.Count; if (count <= 1) { this.bindingNavigatorDeleteItem.Enabled = false; } } private void bindingNavigatorAddNewItem_Click(object sender, EventArgs e) { this.xXXBindingSource.AddNew(); this.bindingNavigatorDeleteItem.Enabled = true; }
質問者さんのケースでうまく行くかどうか分かりませんが、試してみてください。
すべての返信
-
自己レスです。
BindingNavigatorのDeleteItemプロパティを(なし)にし、
DataGridViewを継承したクラスを作り、protectedのProcessDeleteKeyを呼び出す(内部的にDelキーと同じ処理を行う)ようにクリックイベントをコーディングしたらExceptionは出なくなりました。
class DataGridViewEx : DataGridView { public void Delete() { this.ProcessDeleteKey(Keys.Delete); } }
private DataGridViewEx DataGridView1; this.DataGridView1 = new DataGridViewEx(); ・・・ private void bindingNavigatorDeleteItem1_Click(object sender, EventArgs e) { DataGridView1.Delete(); }
参考:フォーラムの「RowValidated イベントハンドラをもつ DataGridView で行を削除するには」
-
そもそもBindingNavigatorは削除確認が出ないので、以下を参考にして削除確認を出した方が良いでしょう。
Visual Studio 2005のフォームにおけるBindingNavigatorの拡張
http://internetcom.jp/developer/20060627/26.htmlこの削除確認のロジックでチェックし、削除対象の行が無ければ、そのようなメッセージを出せば良いように思います。
★良い回答には回答済みマークを付けよう! MVP - .NET http://d.hatena.ne.jp/trapemiya/
-
BindingNavigator が bindingNavigatorDeleteItem をコントロールしているらしく、たとえば Form1_Load メソッドで BindingSource.Count の値をしらべてゼロのとき Enabled を false にしても true に戻ってしまいます。
なので bindingNavigatorDeleteItem を BindingNavigator のコントロール下から外してから Enabled を false にしないとダメなようです。
しかし、コントロール下から外すと削除が効かなくなってしまうので、自力でコードを書いて bindingNavigatorDeleteItem のクリックイベントで削除できるようにしてやる必要があります。
Enabled を true に戻す処置も必要になります。それは bindingNavigatorAddNewItem のクリックイベントでやるのがよさそうです。
具体的には:
(1) Visual Studio の Formx.cs [デザイン] 画面で BindingNavigator のプロパティを表示して、その中の AddNewItem と DeleteItem を (なし) に設定する。(Formx.Designer.cd のコードでは null になります・・・が、そちらを修正しないこと)
(2) 既存の Form_Load メソッドに以下のようなコードを追加する。xXXBindingSource は自分のコードに合わせて修正してください。
int count = this.xXXBindingSource.Count; if (count == 0) { this.bindingNavigatorDeleteItem.Enabled = false; }
(3) bindingNavigatorDeleteItem と bindingNavigatorAddNewItem の Click イベントのハンドラを作る。
(4) 上記 (3) で作ったハンドラに以下のようなコードを追加する。xXXBindingSource, xXXDataGridView は自分のコードに合わせて修正してください。
private void bindingNavigatorDeleteItem_Click(object sender, EventArgs e) { this.xXXBindingSource.RemoveCurrent(); int count = this.xXXDataGridView.Rows.Count; if (count <= 1) { this.bindingNavigatorDeleteItem.Enabled = false; } } private void bindingNavigatorAddNewItem_Click(object sender, EventArgs e) { this.xXXBindingSource.AddNew(); this.bindingNavigatorDeleteItem.Enabled = true; }
質問者さんのケースでうまく行くかどうか分かりませんが、試してみてください。