1

なぜこれが起こるのか理解できません。DataSource が BindingSource に設定されている DataGridView があります (フィルタリングとナビゲートの目的で)。

myDataGridView.DataSource = myBindingSource;

アイテムのリストがあります。1 つのアイテムをクリックすると、myBindingSource に対応するフィルターが適用され、結果として myDataGridView の基準を満たす行のみが表示されます。このような:

private void ItemsClicked(object sender, ItemClickedEventArgs e){
     myBindingSource.Filter = e.FilterExpression;
}

myDataGridView に少なくとも 1 行を表示させる項目をクリックすると、問題なく動作します。しかし、対応するフィルター式を満たす0行になるアイテムをクリックすると、事態は悪化します。myDataGridView は通常は空である必要がありますが、一部のダイアログで多くの例外がスローされます (結果として表示されます) (例外はコード エディター ウィンドウに黄色のマーカーで表示されません)。エラー ダイアログのスナップショットを次に示します。

ここに画像の説明を入力

[OK] ボタンをクリックした後も、別の (同じ) ダイアログが表示されます。... すべて停止するまで、多くのダイアログ (同じメッセージを持つ) が表示され続けます。それが何なのか理解できません。さらに詳しい情報が必要かどうかはわかりませんが、同様の例外が発生したことがあり、これを修正する方法について何か提案をいただければ幸いです。ダイアログには DataError イベントに関するメッセージが表示されますが、ここでエラーが発生する理由がわかりません。フィルターを適用した後、dataGridView に少なくとも 1 つの行がある場合、すべてのフィルターは問題ないことに注意してください。エラーは、フィルターの後に行がない場合にのみ発生します。

助けてください、よろしくお願いします!

4

2 に答える 2

3

これが私の答えです。これはよくわかりませんが、試してみたところ、魅力のように機能します。

私のルールは次のとおりです。

  1. SuspendBinding()フィルターを適用する前に、次のようなメソッドを使用して BindingSource からすべてのコントロールを SuspendBinding します。

    myBindingSource.SuspendBinding();

  2. 次に、次のように通常どおりフィルターを適用します。

    myBindingSource.Filter = "filter expression";

  3. 最後に、ResumeBinding()メソッドを使用して、次のようにすべてのコントロールを BindingSource に再バインドします。

    myBindingSource.ResumeBinding();

それだけです。実際、myBindingSource には、バインドされている多くのコントロールがあります。それが原因なのかもしれませんが、まだよくわかりません。myBindingSource にデータをバインドする myDataGridView しかない場合は、上記の 3 つの手順をすべて行う必要はなく、必要なときにフィルターを適用するだけです (手順 2)。

これが、この問題に遭遇した、遭遇している、そしてこれから遭遇する他の人に役立つことを願っています。繰り返しますが、なぜ機能するのかよくわかりません。誰かがコメントで説明してくれることを願っています。とても感謝しております。ありがとう!

アップデート

上記のようにすると、場合によっては別の問題が発生する可能性があることがわかりました。最も安全な解決策は次のとおりです。

  1. SuspendBinding (上記の説明のように、これは BindingSource の SuspendBinding() メソッドを使用して行われます) ですが、最も安全な方法は、DataSource を null に設定することです。

  2. フィルターを適用します。

  3. ResumeBinding (上記の説明のように、これは BindingSource の ResumeBinding() メソッドを使用して行われます) ですが、最も安全な方法は、自分でコントロールを再バインドすることです (各コントロールをループし、DataBinding の Add メソッドを呼び出します。最初に DataBinding をクリアすることを忘れないでください)。re-bind メソッドを何度も呼び出す可能性があるため、これを行うためのメソッドが必要です。

そして今、私はこのより安全な方法を使用しています。前に述べた方法では、「VersionNotFoundException」と呼ばれる別の例外が発生しました (アクセスする提案されたデータはありません)。例外は ResumeBinding() 呼び出しの行で発生します。そのメソッドには何らかのバグがあるはずです。ただし、マルチテーブルの DataSet を使用しており、同じ dataGridView のテーブルを切り替えています。繰り返しますが、この問題はまだ複雑すぎて、一度に掘り下げて理解することはできません。

真実

フィルターを適用する前にすべてのコントロールのバインディングを一時停止し、その後バインディングを再開する必要がないことがわかりました。私のフォームには、BindingSource の特別な列 (列 X と呼びましょう) にバインドされたコントロールがありますが、なぜこの列が特別なのかまだわかりません。その後、フィルタリングして再度バインドします。他のすべてのコントロール/列は関係ありません。

ここで注目に値する唯一のことは次のとおりです。

=> メイン テーブル (テーブル 1) には A という主キー列があり、このテーブルには B という外部キーがあり、別のテーブル (テーブル 2) の主キー列を参照しています。表 2 には、別の表 (表 3) の C という主キー列を参照する外部キーがあります。実際、すべての列 A、B、C を選択するクエリがありました (もちろん、ここで言及されていないものもあります)。この関係は私が疑っていたものですが、なぜ、どのようにエラーが発生するのかはまだわかりません. バインディングを使用せず、すべての値を手動で割り当て/更新する場合、エラーは発生しません。バインディングは、時には非常に複雑なものです。

于 2013-04-27T01:36:04.253 に答える
1

フィルタリングするものが何もないため、dataGridViewこれを使用してフィルタリングする前に、そのエラーが発生します。

if (dataGridView1.Rows.Count > 0)
{
   //do filter codes here
}

お役に立てれば。

于 2013-04-27T01:17:48.783 に答える