DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ユーザーコントロールに対するFocus

環境/言語:[WindowsXP SP1]
分類:[.NET]

初めて投稿するアダルティと申します。
よろしくお願い致します。

自作のユーザーコントロールに対して、他のコントロールのEnterイベントから
ユーザーコントロールにFocusメソッドを実行すると、1回だけキー入力が
スカってしまう現象があります。
原因が全くつかめないので、ご存知の方、ご回答をお願い致します。


<ユーザーコントロール内のコントロールの構成>
・パネルを1つ配置する
・パネルの子コントロールとして、年,月,日のテキストボックスを配置する


<Focusメソッドの発行>
通常のコントロールと同様、コントロールからフォーカスが離れた瞬間に、
・項目チェック
・エラーがあれば、メッセージ表示&フォーカスを戻す
を行いたいのですが、Leaveイベントだと上手くいかないので
(かつてのLostFocusイベントと同様)、
他コントロールのEnterイベントでチェックを行う方式を採っています。


上記方法でFocusメソッドを発行すると、キー入力がスカってしまうのです。
上記方法ではなく、他コントロールのEnter以外のイベント(例えば、
ボタンのClickイベント等)からFocusメソッドを発行した場合は、何ら
問題はありません。

キー入力がスカる原因として、ユーザーコントロール内の先頭の項目
(年の項目)のEnterイベントが出た後に、なぜかLeaveイベントが出ている事が
原因のようですが、フォーカスを移しただけなのに、どうしてLeaveイベントが
発生してしまうのかが分かりません。

デバッグ実行でブレイクしながら実行すれば上記問題は出ませんが、
かといって、Application.DoEvetnsを発行するようにしても
上手くいかないのです。

ご存知の方、ご回答をよろしくお願い致します。
> 通常のコントロールと同様、コントロールからフォーカスが離れた瞬間に、
> ・項目チェック
> ・エラーがあれば、メッセージ表示&フォーカスを戻す

キー入力がスカる?というのがどのような減少なのかいまいちわかりません。
又、通常値の妥当性チェックはValidatingイベントを使用したほうがいいと
思います。
ご回答ありがとうございます。

> キー入力がスカる?というのがどのような減少なのかいまいちわかりません。

⇒ ユーザーコントロールにフォーカスを移した後、Tabキーが1回だけ
効かなくなってしまう状態です。

この時、見た目上のカーソルはユーザーコントロールの先頭項目にいるよう
に見えますが、実際はどこかに行っちゃっているようなカンジです。
(内部的には、先頭項目のLeaveイベントが出ていて、かつ、
他のコントロールのEnterイベントは出ていない状態です)

上記の状態で、一度Tabキーを押すと、見た目上のカーソル位置は変わり
ませんが、その後の動作は元に戻ります。

仮に、上記状態で、Shift+Tabを押すと、ユーザーコントロール内の最終
項目にカーソルが移ってしまいます。
通常ならば、前コントロールにカーソルが移るはずなのですが・・・。

やはり、イベントが破壊されている状態なのでしょうか・・・。


> 又、通常値の妥当性チェックはValidatingイベントを使用したほうがいいと
> 思います。

⇒ 本来であれば、Validatingイベントを使用したいのですが、一点だけ
解決できない点があるために、使用しかねています。
フォームの×ボタンClick時,Alt+F4押下時にValidatingイベントを無視
できないのです。
要は、×ボタン,Alt+F4 を CausesValidation=Falseの扱いにしたいの
です。
これができればValidationにしたいのですが、解決策はご存知でしょうか?

便乗質問にあってしまい申し訳ありませんが、よろしくお願いします。
おはようございます、アダルティさん。
ユーザコントロールでのイベントがおかしい点はわかりませんが、

■No6184に返信(アダルティさんの記事)
> ⇒ 本来であれば、Validatingイベントを使用したいのですが、一点だけ
>    解決できない点があるために、使用しかねています。
>    フォームの×ボタンClick時,Alt+F4押下時にValidatingイベントを無視
>    できないのです。
>    要は、×ボタン,Alt+F4 を CausesValidation=Falseの扱いにしたいの
>    です。
>    これができればValidationにしたいのですが、解決策はご存知でしょうか?

Me.ActiveControl == 自分自身 -> 「×」ボタンを押下した。
(というより、厳密にはFocusを維持しているから検証しなくても良い)
毎回書くのは面倒だから、そういうイベントを自作すれば良いでしょう。

Private Sub ExControl_Validating(ByVal sender As Object, ByVal e As CancelEventArgs) Handles MyBase.Validating
    If MyClass.FindForm().ActiveControl Is Me = False Then
        RaiseEvent MyValidate(sender, e)
    End If
End Sub

で、MyValidateで検証すればよいのでは?
「e」はCancelEventArgsなので、Cancel可能ですし。
ご回答ありがとうござました。

■No6185に返信(java.lang.Nullpoさんの記事)
> Me.ActiveControl == 自分自身 -> 「×」ボタンを押下した。
> (というより、厳密にはFocusを維持しているから検証しなくても良い)
> 毎回書くのは面倒だから、そういうイベントを自作すれば良いでしょう。

目からウロコでした。
Validatingイベント内で遷移先のコントロールが判定できるのですね。
試したところ、バッチリ上手くいきました!

ということは、ユーザーコントロールに限らず全てのコントロールの
Validationイベントで上記制御を入れれば済むので、今後が非常に
ラクになりました!

ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板