3

シナリオ:

基本的に私は

  • System.Windows.Forms.DataGridView

  • BindingSource と IBindingList を継承するクラス

  • 2 つの標準 List をプライベート プロパティとして持つクラス

DataGridView dgv = 新規 ...

MyBindingSource bindingSource = new ...

MyList リスト = 新規 ...

DataGridView.DataSource プロパティが BindingSource に設定され、BindingSource.DataSource がリストのプライベート リストの 1 つに設定されます。

bindingSource.DataSource = list.ListA;

dgv.DataSource = bindingSource;

データベースから大量の情報ストリーミングを取得しています。情報をオブジェクトに変換し、一度に 1 つずつ MyList に追加すると、最終的に DataGridView に表示されます。

すべてが理にかなっていることを願っていますが、問題は次のとおりです。単一のオブジェクトをリストに追加した後 (バインディングソースではありません)、アイテムを DataGridView に表示したいと考えています。しかし、現在それを機能させる唯一の方法は、1 つの新しいオブジェクトが追加された bindingSource の別のインスタンスを構築し、DataGridView.DataSource を新しい bindingSource に設定することです。もちろん、これは恐ろしく非効率的であり、データグリッドビューは毎回すべてを無効にする必要があり、危険です。

代わりに、DataGridView に新しいオブジェクトが追加されたことを通知する BindingSource を List に通知して、それを行うことができるようにします。これを試しましたが、「インデックス -1 のアイテムには値がありません」という IndexOutOfrange 例外が発生し続けました。BindingSource を調べたところ、実際には位置が -1 で、Current プロパティが同じ例外をスローしました。位置と現在のプロパティが正しいたびに新しい BindingSource を作成すると。

では、項目をリストに追加したときにこれらのプロパティを更新するにはどうすればよいでしょうか? リフレクターで開いて、どこに設定されているかを確認したところ、「CurrencyManager」が関係しているように見えました。base.OnDataMemberChanged base.OnListChanged のようないくつかのことを試しましたが、役に立ちませんでした。

編集:データグリッドビューの行をクリックしたときにのみ例外が発生することを忘れていました。アイテムが正常に追加されます。したがって、DataGridView が BindingSource と同期していないようです

4

3 に答える 3

2

DataSource がコンテンツを変更している場合、DataGridView はそのグリッドをクリアし、SelectionChanged イベントを発生させ、その他のイベントはユーザーの操作に関連付けられます。イベントが発生したときに表示されるデータがまったくないことを知っておくことは重要です。そのため、SelectionChanged イベント リスナーを取得し、内部の行または列にアクセスしている場合、行にアクセスするときに範囲外の例外が発生します。解決策: データグリッド リソースを使用する前に、必ず Rows.count の値を 0 と照合してください。乾杯

于 2010-05-18T16:40:34.900 に答える
1

代わりに BindingList(generic) を使用すると、アイテムの追加/削除と個々のアイテムの変更も通知されます。( http://msdn.microsoft.com/en-us/library/ms132679.aspx )

于 2010-02-25T08:08:28.397 に答える
1

ObservableCollectionの使用を検討しましたか? コレクションに項目が追加または削除されるたびに、バインド先のコントロールが更新されたことを通知します。コレクション内のアイテムのプロパティでも同じことが行われます (ただし、イベントを手動で発生させる必要があります)。

何が例外を引き起こしているのかわかりません

于 2010-02-25T02:52:29.993 に答える