- PR -

Validatingイベントの抑止をキーボード操作でも実行させるには?

投稿者投稿内容
cobalt
会議室デビュー日: 2005/05/02
投稿数: 14
投稿日時: 2005-06-10 18:31
 WindowsフォームにてテキストボックスのValidating時に入力チェックを行っているのですが、特定のボタンを押した時のみチェックが走らないようにしたいのです、ボタンのCausesValidationプロパティをfalseにする事で対応しました。

 フォーム上にコントロールが
  テキストボックスA → ボタン → テキストボックスB
 のタブインデックスの順にあったとして、テキストボックスAのValidatingイベントに入力チェック、ボタンのClickイベントに"閉じますか?"のダイアログを表示してYesならDisposeを呼んでFormを終了、Noなら即returnする処理があります。

 この状況でマウスでボタンをクリックすると閉じますかのダイアログが表示された正常に処理が終了するのですが、フォーカスがテキストボックスAにある時にTabキーを押してフォーカスをボタンに移し、Enterキーを押すとボタンのクリックイベントではなくてテキストボックスAのValidatingイベントが走ってしまいます。
 正常にテキストボックスAのValidatingイベントを走らせたいのですが、何か対処法を知っている方がいましたらご教授お願いします。



以下ソース抜粋
---------------------------------------------------------------
private void txtSample_Validating(object sender, System.ComponentModel.CancelEventArgs e)
{
TextBox obj = (TextBox)sender;

if( obj.Text.Length < obj.MaxLength )
{
MessageBox.Show( "桁が足りていません" );
e.Cancel = true;
}
}

private void btn戻る_Click(object sender, System.EventArgs e)
{
DialogResult dialogResult = MessageBox.Show(
"閉じて良いですか?",
"",
MessageBoxButtons.YesNo
);
if( dialogResult == DialogResult.No )
{
return;
}

this.Dispose();
}
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-06-11 06:33
Enterの代わりに、Spaceキーだとどうなりますか?

Formのプロパティに、Enterボタンを押したときにクリックしたとみなすボタン、というのがあるのですが、そこが空白になっていると思います。その辺が関係あるように思います。

# ちなみに、Formの×ボタンはCasusesValidationをfalseにできないorz
_________________
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2005-06-11 09:17
こんにちは、じゃんぬ です。

引用:

# ちなみに、Formの×ボタンはCasusesValidationをfalseにできないorz



If Me.ActiveControl Is そのコントロール Then
  Return
End If

'/ Validating の処理

とするしかないですね。
面倒なので、カスタムコントロールで私は実装しています。



_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
rucio
ベテラン
会議室デビュー日: 2002/11/27
投稿数: 98
投稿日時: 2005-06-11 17:45
私はValidatingイベントプロシージャの先頭に次のように記述しています。
If ActiveControl.CausesValidation = False Then
Exit Sub
End If

なお、VS2005ではこの点は改善されているようです。
cobalt
会議室デビュー日: 2005/05/02
投稿数: 14
投稿日時: 2005-06-13 13:09
皆様返信ありがとうございます。


引用:
Enterの代わりに、Spaceキーだとどうなりますか?

Formのプロパティに、Enterボタンを押したときにクリックしたとみなすボタン、というのがあるのですが、そこが空白になっていると思います。その辺が関係あるように思います。



Spaceキーだと基本上手くいくみたいですが、偶にトグルボタン見たいにボタンが押しっぱなしになる時があります。
それとお客様に出す物なのでSpaceキーで代用して下さいとは言い辛い。

Enterボタンを押したときにクリックしたとみなすボタンの事ですがAcceptButtonの事でしょうか?
AcceptButtonに閉じるのボタンを設定してもエラーがある状態でEnterキーを押したらValidatingが走ってしまっています。


引用:
If Me.ActiveControl Is そのコントロール Then
  Return
End If



スレッドに書いていませんがこの方法も試したのですが、上手く動いてはいるのですが、
1.テキストにエラーとなる文字列を入れる
2.Tabキーでボタンに移動
3.Enterキーでボタンクリック
4.閉じるかどうかのダイアログでいいえを選択
5.Tabキーをクリック
すると、テキストにエラーがあるにTabIndexがボタンの次のコントロールに移動してしまいます。
複雑な方法ですけどチェックがかかっているのにフォーカスが外れる事が出来るので駄目でした。


引用:
If ActiveControl.CausesValidation = False Then
Exit Sub
End If



こちらもじゃんぬねっとさんのソースと同じ方法で抜ける事ができました。


現状、ボタンの前後にチェックすべきコントロールがある画面が無い事が分かったので対応しないと言う事になりましたが、今後も何か情報がありましたらよろしくお願いします。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-06-13 22:13
これっぽい
PRB:なしが CommandButton をアクティブにしないとき、 Validate イベントがなしだ。
違う。VB6か。かつ、Validatingイベントが発生しない問題らしい。

 う〜ん、なんか、仕様っぽい。テキストボックス2つと、ボタン3つを持ったフォームを用意しました。タブ順序は、TextBox1→Botton1→TextBox2→Button2→Button3→TextBox1としました。Button1とButton3のCauseValidatingプロパティをFalseにしました。TextBox1の、Validating, Enter, GotFocus, Leave, LostFocusイベントに、それぞれイベント名を出力するコードを実装しました。
コード:
	Private Sub TextBox1_Validating(...) Handles TextBox1.Validating
		System.Diagnostics.Debug.WriteLine("TextBox1.Validating")
		If Me.TextBox1.Text.Length = 0 Then e.Cancel = True Else e.Cancel = False
	End Sub

	Private Sub Button3_Click(...) Handles Button3.Click
		Me.TextBox1.Text = String.Empty
	End Sub

	Private Sub TextBox1_Enter(...) Handles TextBox1.Enter
		System.Diagnostics.Debug.WriteLine("TextBox1.Enter")
	End Sub

	Private Sub TextBox1_GotFocus(...) Handles TextBox1.GotFocus
		System.Diagnostics.Debug.WriteLine("TextBox1.GotFocus")
	End Sub

	Private Sub TextBox1_Leave(...) Handles TextBox1.Leave
		System.Diagnostics.Debug.WriteLine("TextBox1.Leave")
	End Sub

	Private Sub TextBox1_LostFocus(...) Handles TextBox1.LostFocus
		System.Diagnostics.Debug.WriteLine("TextBox1.LostFocus")
	End Sub


これで、TextBox1にフォーカスがある状態から、TABキーを2度キー入力すると、
引用:

TextBox1.Enter
TextBox1.GotFocus
<TAB>
TextBox1.Leave
TextBox1.LostFocus
<TAB>
TextBox1.Validating
//TextBox2のEnter, GotFocus


のように、イベントが発生します。TextBox1にフォーカスがある状態で、TAB, Enterとキー入力すると、
引用:

TextBox1.Enter
TextBox1.GotFocus
<TAB>
TextBox1.Leave
TextBox1.LostFocus
<ENTER>
TextBox1.Validating


のようにイベントが発生します。FormのAcceptButtonにButton1を指定しても、同じですね。Button1とButton3を交互にマウスクリックしても、Validatingイベントは発生しません。しかし、それら以外のコントロールにフォーカスを移動しようとすると、発生します。

 ん〜、ドキュメントのフィードバックで報告してみるか?


rucioさん>
> なお、VS2005ではこの点は改善されているようです。
おお!・・・確かに、改善されているけど、中途半端。。。
 FormのCausesValidationをFalseにします。フォーカスがValidatingを行うコントロールにある間は、フォームを閉じられません。しかし、CausesValidationがFalseのコントロールにフォーカスがあれば、閉じられました。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-06-18 08:48
 マイクロソフトのデベロッパー製品開発部の方で、バグとして認識されました。

 追加の報告がありましたら、こちらにもフィードバックします。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-06-27 19:51
引用:

> なお、VS2005ではこの点は改善されているようです。
おお!・・・確かに、改善されているけど、中途半端。。。
 FormのCausesValidationをFalseにします。フォーカスがValidatingを行うコントロールにある間は、フォームを閉じられません。しかし、CausesValidationがFalseのコントロールにフォーカスがあれば、閉じられました。


 こちらを、VS2005のFeedback Centerに、バグとして報告しました。
Bug Details: CausesValidation を false にした時の動作について

 他のユーザによって再現性が確認され(Can validate)、優先順位が高いと投票される(Average voter rating)と、高い優先度で修正してもらえるそうです。

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