- 締切済み
コントロールが発生させるイベントを回避したい
VB2008です。 状態: フォーム上にtextbox1、textbox2、button1があり、textbox1からtextbox2もしくはbutton1にフォーカスが移動したとき 1:textbox2への移動->textbox1のlostfocusイベントを通常通り発生させる。 2:button1への移動->textbox1のlostfocusイベントをキャンセルする。(1度たりとも発生させない、もしくは発生してもその処理を1度たりともさせない。) 1は通常の処理なのでなにもしなくていいと思うのですが、2の処理が上手に浮かびません。button1でフラグを立てて、textbox1_lostfocusの処理を抜けるようにしているのですが、必ず1度は処理が実行されます。 どのようにコードを書けばうまくできるでしょうか。もし、これが仕様ということなら、同じような処理をするにはどうすればよいでしょうか。 わかりにくければ補足いたします。よろしくお願いします。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- pulsa
- ベストアンサー率57% (34/59)
概念としてNO.2の方で正解ですね lostfocus→getfocus のように進まないと、一時的にfocusが二つあることになってしまいますもんね 今回の場合、lostfocusには処理は入れられません getfocusの時lostfocusに入れていたイベントの内容を実行させるのが、良いかと思います もう少し突っ込むと、textbox1のlostfocusが重要なのではなく、 「textbox2がgetfocusした時、直前がtextbox1だった事」が重要と考えます NO.2の方のように、フラグでも良いでしょうし、全てのlostfocusに抜けるコントロールの名前を変数に入れさせるようにして、変数の値が「"textbox1"」の時だけ反応するようにgetfocusのイベントの先頭にこれまでtextbox1のlostfocusに書いていた処理を実行させるのも手です 質問内容によるとbutton1のgetfocusには不要ですので、何も書かなければ、実行されません つまり、変数の判断処理自体不要です lostfocusするときに、変数が更新されるので、初期化は考慮しなくて済みます 関数化して Call CtrlChack(Ctrl) と呼んでみます ↑これを実行させる可能性のあるgetfocusの先頭に書いておく Dim Ctrl As String 'これまでfocusがあったコントロール ↑これをFormモジュールの先頭に書いておく Private Sub TextBox1_LostFocus() Ctrl = "TextBox1" End Sub Private Sub TextBox2_LostFocus() Ctrl = "TextBox2" End Sub Private Sub TextBox2_GotFocus() Call CtrlChack(Ctrl) 'こんな感じ End Sub Private Sub Button1_GotFocus() '処理不要なので特にtextbox1のlostfocusに関係する処理なし End Sub ↓これは標準モジュールでOK(Formモジュールでも良いハズですが…) Sub CtrlChack(Ctrl As String) If Ctrl = "TextBox1" Then 'textbox1のlostfocusに書いてた処理 End If End Sub
- DexMachina
- ベストアンサー率73% (1287/1744)
AccessのVBAしか扱ったことのない者ですが(汗)、概念としては共通でいけると思いますので・・・ 移動元のFocus喪失系のイベントが終了してからでないと、移動先のFocus取得系のイベントは 発生しないので、移動先でのフラグ処理では間に合わないと推測されます。 従って、移動先によるLostFocusイベントの切り分けは無理だと思いますので、以下はその前提での 対策になります。 1)TextBox1のLostFocusイベントでは、「TextBox1のLostFocusイベントが発生したこと」を記録する フラグだけを立てます(変数EveFlag=True) 2)Button1のGotFocusイベントでは、上記フラグを元に戻します(EveFlag=False) 3)TextBox1のLostFocusイベントで行いたかった処理を、イベントとは無関係のPrivate Subとして フォーム モジュールに記述します(WhenMoveFromTB1) 4)TextBox1・Button1以外の、Focusを取得できる全コントロールのGotFocusイベントで、上記フラグが オンだった場合は、上記Private SubをCallします ・・・以上が概念です。 コードの実例は以下の通り: Option Explicit 'フォームのモジュールレベルでフラグを宣言 Dim EveFlag As Boolean Private Sub TextBox1_LostFocus() 'TextBox1のLostFocusイベントが発生したことをフラグに記録 EveFlag = True End Sub Private Sub WhenMoveFromTB1() 'フラグの初期化 EveFlag = False 'ここ(↓)には、現在、TextBox1のLostFocusイベントに記述している処理を転記 MsgBox "LostFocusイベントの処理を代行します。" End Sub Private Sub TextBox2_GotFocus() 'TextBox1のLostFocusイベントが必要なTextBox2では、代行するSubをCall If EveFlag = True Then Call WhenMoveFromTB1 End Sub Private Sub Button1_GotFocus() 'TextBox2のLostFocusイベントが無用のButton1では、フラグの初期化のみを実行 EveFlag = False End Sub Private Sub TextBox3_GotFocus() 'TextBox1のLostFocusイベントの起動が必要なコントロールがTextBox2以外にも 'ある場合は、TextBox2と同様に、代行SubをCall If EveFlag = True Then Call WhenMoveFromTB1 End Sub ・・・以上です。
お礼
お返事ありがとうございました。 結局フラグを立てるのもめんどくさくなりtextbox2のenterイベントで処理するようにしました。
- onnobu
- ベストアンサー率33% (1/3)
LeaveイベントのActiveContorolのプロパティーの項目に button1だけでしたら、ActiveContorol.Name = "button1"などで処理を回避できます。 また、プロパティー名を忘れてしまいましたが、buttonコントロール全体を回避することもできますよ。
お礼
お返事ありがとうございました。 textbox2のenterイベントで処理するようにしました。
お礼
お返事ありがとうございました。 textbox2のenterイベントで処理するようにしました。