C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[1]: チェックボックスイベント中は操作無効にしたい


(過去ログ 177 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■101771 / inTopicNo.1)  チェックボックスイベント中は操作無効にしたい
  
□投稿者/ 夢ババ (1回)-(2023/04/17(Mon) 14:44:46)

分類:[VB.NET/VB2005 以降] 

VB2019でWindowsフォームのプログラムを作成しています。

チェックボックスのクリックでチェックON/OFFを行うとき、
チェックボックスのCheckedChangedイベントで処理を行っています。
ただ、このCheckedChangedイベントで処理を実行中に
このチェックボックス上でクリックを行うと、
クリックのリクエストが残っているのか、
再度チェックボックスのON/OFFが切り替わり、
またCheckedChangedイベントが走ってしまいます。

最初のCheckedChangedイベントの処理が終わるまでは
例えそのチェックボックス上でクリックを行っても
チェックボックスのON/OFF切り替わりを無効にしたいのですが、
どのようにすればよいのでしょうか?

このチェックボックスのCheckedChangedイベントの最初で
このチェックボックスのEnabledをFalseにして、
このイベントの処理が終わってからこのチェックボックスのEnabledをTrueにする、
ということを試してみましたが、
このイベント処理中にチェックボックスをクリックしたことを記憶しているようで、
このイベント処理が終わったとたんに再度CheckedChangedイベントが走りました。
引用返信 編集キー/
■101772 / inTopicNo.2)  Re[1]: チェックボックスイベント中は操作無効にしたい
□投稿者/ WebSurfer (2671回)-(2023/04/17(Mon) 15:06:24)
No101771 (夢ババ さん) に返信

> ただ、このCheckedChangedイベントで処理を実行中に
> このチェックボックス上でクリックを行うと、

どういう処理なのでしょう?
引用返信 編集キー/
■101774 / inTopicNo.3)  Re[1]: チェックボックスイベント中は操作無効にしたい
□投稿者/ 魔界の仮面弁士 (3623回)-(2023/04/17(Mon) 16:17:54)
No101771 (夢ババ さん) に返信
> 再度チェックボックスのON/OFFが切り替わり、
> またCheckedChangedイベントが走ってしまいます。

イベント内で、「On/OFF いずれの状態であるのか」を確認すれば良いのでは?

Dim chk = DirectCast(sender, CheckBox)
If chk.Checked Then
 
End If
引用返信 編集キー/
■101775 / inTopicNo.4)  Re[1]: チェックボックスイベント中は操作無効にしたい
□投稿者/ KOZ (400回)-(2023/04/18(Tue) 06:02:21)
No101771 (夢ババ さん) に返信
> このチェックボックスのCheckedChangedイベントの最初で
> このチェックボックスのEnabledをFalseにして、
> このイベントの処理が終わってからこのチェックボックスのEnabledをTrueにする、
> ということを試してみましたが、
> このイベント処理中にチェックボックスをクリックしたことを記憶しているようで、
> このイベント処理が終わったとたんに再度CheckedChangedイベントが走りました。

Application.DoEvents() を入れるといいかも。

Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) _
                Handles CheckBox1.CheckedChanged
    Dim box = DirectCast(sender, CheckBox)
    box.Enabled = False
    Try
        Debug.Print("Enter CheckedChanged")
        Threading.Thread.Sleep(3000) ' 長い処理
        Debug.Print("Exit  CheckedChanged")
    Finally
        Application.DoEvents()
        box.Enabled = True
    End Try
End Sub

引用返信 編集キー/
■101776 / inTopicNo.5)  Re[1]: チェックボックスイベント中は操作無効にしたい
□投稿者/ radian (122回)-(2023/04/18(Tue) 11:09:07)
2023/04/18(Tue) 15:03:25 編集(投稿者)
No101771 (夢ババ さん) に返信
> このチェックボックスのCheckedChangedイベントの最初で
> このチェックボックスのEnabledをFalseにして、
> このイベントの処理が終わってからこのチェックボックスのEnabledをTrueにする、
> ということを試してみましたが、
> このイベント処理中にチェックボックスをクリックしたことを記憶しているようで、
> このイベント処理が終わったとたんに再度CheckedChangedイベントが走りました。

フレームワークのバージョンが記入されていませんが、
非同期に対応しているバージョンならイベントにAsyncを付けて非同期にすればいいと思います。

Public Class Form1

    Private Async Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox1.CheckedChanged
        CheckBox1.Enabled = False
        TextBox1.Clear()
        TextBox1.AppendText("処理開始" & vbCrLf)
        For i As Integer = 1 To 5
            Await Task.Delay(1000)
            TextBox1.AppendText($"{i}秒経過" & vbCrLf)
        Next
        TextBox1.AppendText("処理終了" & vbCrLf)
        CheckBox1.Enabled = True
    End Sub

End Class

非同期に対応していない場合は、BackgroundWorkerでチェックボックス処理を実行し、
RunWorkerCompletedイベントでチェックボックスを戻せばいいんじゃないでしょうか。

https://learn.microsoft.com/ja-jp/dotnet/api/system.componentmodel.backgroundworker


非同期にしない場合、イベントは内部的にキューに積まれて順次処理されるので、
CheckedChangedイベント内の処理が完了するまで、
他のイベント処理は待機されます。
そして、CheckedChangedイベント内でEnabledをTrue、Falseしたところで、
CheckedChangedイベントが終わった時点で、他のイベントが処理される前に
Enabledは元に戻っているので特に意味はありません。

Application.DoEventsで、強制的にキューに積まれているイベントを
実行させる事は可能ですが、Application.DoEventsの注意事項にある通り
Microsoftは非同期プログラミングを推奨しています。
イベントの完了状況の把握が困難になるので、私はDoEventsはお勧めしません。

https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.forms.application.doevents

引用返信 編集キー/
■101778 / inTopicNo.6)  Re[1]: チェックボックスイベント中は操作無効にしたい
□投稿者/ 大谷刑部 (235回)-(2023/04/18(Tue) 11:51:01)
No101771 (夢ババ さん) に返信
> このチェックボックスのCheckedChangedイベントの最初で
> このチェックボックスのEnabledをFalseにして、
> このイベントの処理が終わってからこのチェックボックスのEnabledをTrueにする、
> ということを試してみましたが、
> このイベント処理中にチェックボックスをクリックしたことを記憶しているようで、

挙動上そう見えるかもしれませんが厳密には違います。
おそらくは非同期に処理が進行しているため、CheckedChangedで行っている処理が終了する前にTrueに戻す処理が先に反映されてしまい、「クリックできる」状態にもどってしまうということです。

> このイベント処理が終わったとたんに再度CheckedChangedイベントが走りました。

ということでこの挙動は.Netの仕様通りということになります。

なので確実に処理中はクリックできないようにするには、他の方が提示しているように、EnabledをTrueにする処理の前に何らかのWait処理をいれて同期処理にするしかありません。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -