- PR -

VB.netのValidatingイベントについて

1
投稿者投稿内容
マー坊
会議室デビュー日: 2005/04/27
投稿数: 6
投稿日時: 2005-05-09 21:32
開発環境 VB.net .NET Framework SDK v1.1

1.条件
VB.netにてフォームに二つのテキストボックスがあります。

@txtJisekiSu
AtxtSiziSu


@のtxtJisekiSuという名称のテキストボックスに下記のようなValidating
イベントを書きました。

Private Sub txtJisekiSu_Validating(ByVal sender As  ・・・・省略

e.Cancel = True

End Sub

AのtxtSiziSuという名称のテキストボックスに下記のようなEnter
イベントを書きました。

Private Sub txtSiziSu_Enter(ByVal sender ・・・・省略

txtSiziSu.BackColor = g_TextBoxBackColor2 '背景色変更

End Sub


2.現象
txtJisekiSu(テキストボックス)にフォーカスがある場合に
本来ならtxtJisekiSu(テキストボックス)でのValidatingイベント
のe.Cancel = TrueによりtxtSiziSu(テキストボックス)をクリックしても
txtSiziSu(テキストボックス)のEnterイベントは発生しないはずです。
しかし何度もtxtSiziSu(テキストボックス)をクリックするとまれに
Enterイベントは発生してしまいます。
これは不具合なのでしょうか?それとも私のコードに問題があるのでしょうか?



Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-05-09 23:37
引用:

マー坊さんの書き込み (2005-05-09 21:32) より:

本来ならtxtJisekiSu(テキストボックス)でのValidatingイベント
のe.Cancel = TrueによりtxtSiziSu(テキストボックス)をクリックしても
txtSiziSu(テキストボックス)のEnterイベントは発生しないはずです。
しかし何度もtxtSiziSu(テキストボックス)をクリックするとまれに
Enterイベントは発生してしまいます。

これは不具合なのでしょうか?それとも私のコードに問題があるのでしょうか?


 マニュアルをきちんと読んでいないことが原因と思われます。EnterイベントはValidatingイベントより先に発生します。

引用:

[Control.Validatingイベント]より:

マウスを使用するか Focus メソッドを呼び出してフォーカスを変更するとき、フォーカス イベントは次の順序で発生します。

1.Enter
2.GotFocus
3.LostFocus
4.Leave
5.Validating
6.Validated

Validating イベント デリゲートで CancelEventArgs オブジェクトの Cancel プロパティが true に設定されると、通常は Validating イベントの後に発生するすべてのイベントが発生しなくなります。


_________________
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2005-05-10 00:39
引用:
マニュアルをきちんと読んでいないことが原因と思われます。EnterイベントはValidatingイベントより先に発生します。


ご指摘のイベント発生順序は ひとつのコントロールについて 述べられているのでは? コントロール1 の Validating と コントロール2 の Enter の発生順序については記述されていないですよね?

コントロール1 の入力検査が完了していないのに 他のコントロール2 に Enter/GotFocus するのは不便な気がします。けど、5.Validating のときには、そのコントロールは 3.LostFocus / 4.Leave を完了しているので、他のコントロールが 1.Enter / 2.GotFocus できてしまう可能性はありそうですね。なぜ、LostFocus のあとに Validating するという仕様になっているんでしょうね・・・。大丈夫なんでしょうか。

ちなみに、Java(Swing) では、LostFocus よりも先に InputVerify(入力検査) が行われ、入力検査に失敗した場合は LostFocus 自体が発生しません。なので、他のコントロールにフォーカスが移ることはありえないようになっています。
よねKEN
ぬし
会議室デビュー日: 2003/08/23
投稿数: 472
投稿日時: 2005-05-10 01:11
引用:

マー坊さんの書き込み (2005-05-09 21:32) より:
2.現象
txtJisekiSu(テキストボックス)にフォーカスがある場合に
本来ならtxtJisekiSu(テキストボックス)でのValidatingイベント
のe.Cancel = TrueによりtxtSiziSu(テキストボックス)をクリックしても
txtSiziSu(テキストボックス)のEnterイベントは発生しないはずです。
しかし何度もtxtSiziSu(テキストボックス)をクリックするとまれに
Enterイベントは発生してしまいます。



実験してみました。
新規にプロジェクトを作成して、TextBox1とTextBox2を配置。
TextBox1にValidatingイベントを、TextBox2にEnterイベントを記述しました。

コード:
    Private Sub TextBox1_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating
        e.Cancel = True
    End Sub

    Private Sub TextBox2_Enter(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox2.Enter
        Me.BackColor = Color.White
    End Sub



プロパティがデフォルトのままでも、
CausesValidationプロパティをいろいろいじってみても、
別途Buttonを配置してみて、同様にCausesValidationプロパティをいじってみても、
おっしゃるような現象は再現できませんでした。
理屈から言えば、遷移元のValidatingイベントより遷移先のEnterイベントが
先に発生するとは思えません。(それじゃあ、Validatingにならない)

再現できる必要最小限のソースコードを作成されてはいかがでしょうか?
その中で原因が絞り込めるのではないかと思います。

#しかし、TextBox2で右クリックでコンテキストメニューが表示できてしまい、
#貼り付けを選んで、TextBox2に入力できてしまいました・・・。
#これはValidatingの動作としてまずいのでは・・・・

Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-05-10 22:52
未記入さん>
> ご指摘のイベント発生順序は ひとつのコントロールについて 述べられているのでは?
その通りでした。。。

System.Windows.Forms.TextBox, Text: textBox2: Enter
System.Windows.Forms.TextBox, Text: textBox2: GotFocus
-- ここでアクションを起こす --
System.Windows.Forms.TextBox, Text: textBox2: LostFocus
System.Windows.Forms.TextBox, Text: textBox2: Leave
System.Windows.Forms.TextBox, Text: textBox2: Validating
System.Windows.Forms.TextBox, Text: textBox2: Validated
System.Windows.Forms.TextBox, Text: textBox1: Enter
System.Windows.Forms.TextBox, Text: textBox1: GotFocus

Cancelしたとき
System.Windows.Forms.TextBox, Text: textBox1: Enter
System.Windows.Forms.TextBox, Text: textBox1: GotFocus
-- ここでアクションを起こす --
System.Windows.Forms.TextBox, Text: textBox1: LostFocus
System.Windows.Forms.TextBox, Text: textBox1: Leave
System.Windows.Forms.TextBox, Text: textBox1: Validating
System.Windows.Forms.TextBox, Text: textBox1: Enter
System.Windows.Forms.TextBox, Text: textBox2: LostFocus
System.Windows.Forms.TextBox, Text: textBox1: GotFocus

 なお、LostFocusイベントは、キーボードでフォーカスを移動するか、マウスで移動するかによって、発生するタイミングが変わります。おいおい...


マー坊さん>
 TextBox1のValidatingでCancelするようにし、TextBox2をクリックしまくりましたが、textBox2のEnterイベントは発生しませんでした。GotFocusイベントが発生していないのにLostFocusイベントが発生しているのが気になりますが。

 なお、.NET Framework 1.1 ServicePack1はあてていますか?なにやら怪しいものがゾロゾロ。。。

-----
以下、フィードバック内容(別名、いいわけ)
引用:

JPN Documentation Feedback (v1.1): systemwindowsformscontrol_9.rtf, Validating イベント

1.イベントの発生順序がわかりにくい

>>>>>現状の記述>>>>>
キーボード (Tab、Shift+Tab など) を使用するか、 Select メソッドまたは SelectNextControl メソッドを呼び出すか、 ContainerControl.ActiveControl プロパティを現在のフォームに設定してフォーカスを変更するとき、次の順序でフォーカス イベントが発生します。

1.Enter
2.GotFocus
3.Leave
4.Validating
5.Validated
6.LostFocus


マウスを使用するか Focus メソッドを呼び出してフォーカスを変更するとき、フォーカス イベントは次の順序で発生します。

1.Enter
2.GotFocus
3.LostFocus
4.Leave
5.Validating
6.Validated
<<<<<

わかりにくい点:
 textBox1とtextBox2を配置して、textBox1にフォーカスがある状態とします。ここでTextBox2をクリックすると、
textBox1: LostFocus
textBox1: Leave
textBox1: Validating
textBox1: Validated
textBox2: Enter
textBox2: GotFocus
の様にイベントが発生します。
 textBox1とtextBox2を配置して、textBox1にフォーカスがある状態とし、[Tab]キーを打鍵すると、
textBox1: Leave
textBox1: Validating
textBox1: Validated
textBox1: LostFocus
textBox2: Enter
textBox2: GotFocus
の様にイベントが発生します。

 EnterイベントとGotFocusイベントは、確かにそのコントロールに対しては最初に発生しますが、『キーボードを使用…してフォーカスを変更』『マウスを使用…してフォーカスを変更』等の、イベントを引き起こすアクションを基準に考えると、これらのイベントは最後に発生する、とも言えないでしょうか。
 こう考えるのは、『キーボードを使用…してフォーカスを変更』と、『マウスを使用…してフォーカスを変更』の、2つが書いてあるためです。キーボードでコントロールにフォーカスを移した後、マウスでフォーカスを移す場合、Enterイベント、GotFocusイベントは、前回のキーボードで発生したイベントであり、『マウスを使用…してフォーカスを変更』したから発生したイベントではない、と思います。


改善案:
 1.アクションを起こすところを明記する
   1. Enter
   2. GotFocus
   -- クリックなどのアクションを起こします --
   3. LostFocus
   4. Leave
   5. Validating
   6. Validated

 2.アクションを基準にイベントの順番を記述する
   1. LostFocus
   2. Leave
   3. Validating
   4. Validated
   -- 他のコントロールにフォーカスが移ります --
   -- 以下のイベントは遷移先のコントロールで発生します --
   5. Enter
   6. GotFocus


 Validatingイベントを元にしていますが、Enter, GotFocus, LostFocus, Leave, Validating, Validatedイベントにも同様の記述がありますので、すべてが対象になります。


2.Cancel = trueの時のイベントについて
 『CausesValidation プロパティが false に設定されている場合、 Validating イベントおよび Validated イベントは発生しません。』と書かれていますが、遷移しようとしたコントロールのLostFocusイベントが発生します。
 検証対象のコントロールで発生するイベントではありませんが、LostFocusイベントで何らかの処理をするようなコードを書いていると、誤動作することになります。注意書きが必要ではないでしょうか。
 また、Enterイベント、GotFocusイベントが"再び"発生することについても、記述が必要と思います。

>>>>>実験結果>>>>>
textBox1: LostFocus
textBox1: Leave
textBox1: Validating
textBox1: Enter
textBox2: LostFocus ←ここ
textBox1: GotFocus
<<<<<


 以上、ご検討願います。



_________________
1

スキルアップ/キャリアアップ(JOB@IT)