Windowsフォームでコントロールイベントを一時停止する最良の方法は?
質問
これは非常に単純で非常に一般的な問題のようです。私が考えることができる最も簡単な例はこれです:
フォームには5つのチェックボックスがあり、「すべてチェック/すべてチェックなし」が付いています。それらの上のチェックボックス。ユーザーがすべてのチェックボックスをオンにすることを選択すると、「子供」の状態を切り替えます。 -明らかに、すべてのチェックボックスの設定が完了するまで、すべての子のcheckイベントを発生させたくありません。
フォーム全体のサスペンドコントロールイベントが見つかりません。私がそれを単に見逃しているなら、素晴らしいシンプルな答えです。私が今見逃している単純なソリューションを除いて、フォーム制御イベントを一時停止するための最良の方法は何ですか(ベストプラクティス?承認済みのソリューション?)
解決
私は以前にこれに遭遇しましたが、通常はこれを行う人々を見ました:
/*SNIP*/
private bool isMassUpdate;
public void Check1_Check(object sender, EventArgs e)
{
if(!isMassUpdate)
{
do some stuff
}
}
/*SNIP*/
イベントハンドラーをデタッチおよび再アタッチすることもできますが、これはメモリリークの原因になる可能性があると言われています。
メモリリークとイベントハンドラーに関する情報:これらはアタッチとデタッチに直接リンクされていませんが、アプリケーションの1つで、継承ツリーでのイベントハンドラーの不適切な参照が原因であることがわかりました。
他のヒント
これらの場合、イベントを一時停止するブール値を使用する代わりに、カウンターを使用します。カウントが>の場合0、次にカウント= 0のときにイベントを中断し、イベントを再開します。これは、イベントの一時停止をリクエストできるものが複数ある場合に問題を解決します。
他の便利なことは、ブロック内のイベントを一時停止する必要がある場合、「使用中」で使用できるIDisposableの小さなヘルパークラスを作成することです。 (C#で)ブロックするので、スコープ外になったらカウンターを減らすことを忘れないでください。
他の質問から、VB .NETを使用していると思います。したがって、RemoveHandlerが最善の策です。通常、VBでは、Handles句を使用してイベントハンドラーを設定します。ただし、次の方法でも実行できます。
AddHandler chk1.CheckedChanged, AddressOf DoSomething
DoSsomethingは次のようになります:
Private Sub DoSomething(ByVal sender As Object, ByVal e As EventArgs)
' whatever
End Sub
AddHandlerはイベントを結び付けるため、発生します。起動しないようにするには、RemoveHandlerを使用します。
RemoveHandler chk1.CheckedChanged, AddressOf DoSomething
子チェックボックスのCheckedプロパティを更新する前に、それぞれのRemoveHandlerを呼び出します。その後、完了したら、AddHandlerを呼び出してイベントハンドラーを戻します。すべてのチェックボックスが同じハンドラーを使用する場合、それらをコレクションに入れ、コレクションをループしてハンドラーを追加または削除できます。
チェックを変更するのではなく、ボタンの「クリック」イベントの処理を検討することもできます。それはあなたの意図により近いかもしれません。
Visual Basic 6.0 アプリケーションで、ユーザーがダブルクリックするのを処理する必要がありました< em>すべて、すべてのイベントハンドラーで、グローバル変数をチェックする1行があります
Private bSuspendEvents as Boolean
Private Sub Button1_Click()
On Error Goto ErrorHandler
If bSuspendEvents then Exit Sub
bSuspendEvents = True
'Do stuff
NormalExit:
bSuspendEvents = False
Exit Sub
ErrorHandler:
'Handle Error
Resume NormalExit
End Sub
スタックオーバーフローの質問を参照 C#Windowsフォームで制御状態を変更するときに発生する単純なイベントを無視するにはどうすればよいですか
より一般的な場合、コントロール間に複雑な関係がある場合、独自のFocusedプロパティをチェックすることにより、どのコントロールがイベントを発生させたかを確認できます。各オブジェクトはそれ自身にのみ依存しています。