トップ回答者
[VB2005] TextboxのValidatingイベントによるTabControlの移動制御

質問
-
VB2005でWindowsフォームのアプリケーションを開発しています。
複数のTabPageを持つTabControl内にそれぞれTextboxとButtonが配置してあり、
Textbox.Validatingイベントでは、入力値のチェックを行っております。
チェックの結果、入力値が異常であれば、エラーメッセージを表示し、
e.Cancel=Trueによって移動しないようにしています。
上記のような状態で、Tabを切り替える動作を行うと、エラーメッセージの表示と移動のキャンセルは行われるのですが、
それ以降、TabPage内のButton.Clickイベントが発生しなくなってしまいます。
正常な値を入力して別のTabに切り替えて戻ってくると、Button.Clickイベントが正しく発生するようになりました。
シンプルにe.Cancel=Trueで移動を制御するのは無理なのでしょうか。
回答
-
この例ですと、 e.Cancel = True の後に、MessageBox.Show("TextBox1 validating") などとメッセージボックス(またはモーダルダイアログ)を表示した場合など、質問者さんの現象が再現しないでしょうか?
↑なるほど、こうすると再現しました。(言語は VS2008 Express の C# で試しました。)ところが、画面とコードをいじってから、元に戻す作業(後から追加したコントロール削除とコードのコメント化)をおこなったら、また再現しなくなりました。(なぜだろう。。)ともかく aodus様とおなじと思われる現象を確認することはできましたが現象が出にくいという点では異なるようです。この現象の違いが環境の問題といわれれば、そうかもしれません。.NET のバージョンでいうと、.NET Framework 3.5 SP1 がインストールされています。ちなみにコードをどういじってみたかというと下記コードのとおり else 側でもメッセージ表示してみました。これだと、ボタンをクリックしたときに else 側を通った場合、フォーカスはボタンに移りますがボタンのクリックイベントは実行されませんでした。こうしてみると Validating 自体の実装には大変な苦労があるんだろうなと思いました(v v)private void textBox1_Validating(object sender, CancelEventArgs e){if (textBox1.Text == string.Empty){e.Cancel = true;MessageBox.Show("TextBox1 validating");}else{MessageBox.Show("TextBox1 else");}}以上、とりあえずご報告&etc.でした。- 回答としてマーク 高橋 春樹 2009年10月6日 9:16
-
VS2008(C#)で確認したところ、現象が再現できました。
(元々確認していた環境はVS2005(VB)でした。)
1.TabControl上に配置されたControlのValidatingイベントで、以下の処理を行う。
(1)Cancel=Trueとする
(2)MessageBoxなどのモーダルダイアログを表示する。
2.配置したControlにフォーカスがある状態で、TabPageを切り替える。
→ControlのValidatingイベントが発生する。
ダイアログが表示される。TabPageは替わらない。
3.この後、ControlのValidatingでCancel=Trueとならないようにする。
(今回の例ではTextBoxに何か入力する)
ValidatingでCancelされないのでButtonをクリックできるが、イベントは発生されない。
尚、Form上にComboBoxが配置されている場合、ドロップダウンの▼をマウスクリックすると、
一瞬リストが表示されるが、すぐに閉じてしまいます。- 回答としてマーク 高橋 春樹 2009年10月6日 9:16
-
1.TabControl上に配置されたControlのValidatingイベントで、以下の処理を行う。
↑この手順で繰り返し再現することが確認できました。
(1)Cancel=Trueとする
(2)MessageBoxなどのモーダルダイアログを表示する。
2.配置したControlにフォーカスがある状態で、TabPageを切り替える。
→ControlのValidatingイベントが発生する。
ダイアログが表示される。TabPageは替わらない。
3.この後、ControlのValidatingでCancel=Trueとならないようにする。
(今回の例ではTextBoxに何か入力する)
ValidatingでCancelされないのでButtonをクリックできるが、イベントは発生されない。
マウスダウン、アップイベントは起きるので回避策はとれそうですが…。- 回答としてマーク 高橋 春樹 2009年10月6日 9:16
-
細かいバージョンは分かりませんが、.NET FW 3.5 SP1が入っているPCでも、
入っていないPC(.NET FW 2.0まで)でも、手元の環境では今の所100%再現しています。
根本的な原因は分かりませんが、以下の処理でその場凌ぎはできそうなので何とかしてみます。
(1)Textbox.Validating発生時チェックがパスできない時、以下a,bの分岐を行う
(1.a)ActiveControlがTabControlで無い場合はe.Cancel=True、
(1.b)ActiveControlがTabControlである場合はe.Cancel=Trueを行わず、
フォーカスをsenderに合わせてTab移動不可フラグをTrue、
(2)TabContorl.Deselecting発生時にTab移動不可フラグがTrueならe.Cancel=True
相談に乗っていただき、誠にありがとうございました。- 回答としてマーク 高橋 春樹 2009年10月6日 9:16
すべての返信
-
(C# でですが)試してみました。
C#の開発環境を所持していないので、VC#2008Expressで試してみましたが、同じ挙動になりました。でも再現しません。Button をマウスクリックする前にTextbox 内の入力値はエラー値から正常値に変えてますよね?
会社(VB2005)と自宅(VB2008Express,VC#2008Express)で発生しているのでPC固有の問題ではないと思います。
エラー値のままだと、Button.Clickの前にTextbox.Validatingが発生しますので、
Textbox内の入力値を正常値に変えてからButtonをマウスクリックしています。 -
エラー値のままだと、Button.Clickの前にTextbox.Validatingが発生しますので、
Textbox内の入力値を正常値に変えてからButtonをマウスクリックしています。承知いたしました。
VB2005 でも試してみたのですが再現しませんでした。。
以下、試した内容です。再現しなかったのであれですが御参考まで。。
プロジェクトを新規作成。
タブコントロールの各タブにテキストボックス、ボタンを配置。
コードは後述のとおりです。
テストの実行手順は、、、
実行 → TabPage1 のテキストボックスをクリック
→ TabPage2 のラベルをクリック(タブ移動がキャンセルされます。)
→ テキストボックスに文字入力 → Button1 をマウスクリック(メッセージが表示されます。)
以上の正常動作を確認しました。
Public Class Form1Private Sub TextBox1_Validating(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating
If TextBox1.Text = "" Then
e.Cancel = True
End If
End SubPrivate Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
MessageBox.Show("a click")
End SubPrivate Sub TextBox2_Validating(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles TextBox2.Validating
If TextBox2.Text = "" Then
e.Cancel = True
End If
End SubPrivate Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
MessageBox.Show("b click")
End Sub
End Class -
この例ですと、 e.Cancel = True の後に、MessageBox.Show("TextBox1 validating") などとメッセージボックス(またはモーダルダイアログ)を表示した場合など、質問者さんの現象が再現しないでしょうか?
kanepom さん
Textbox.Validatingでのエラーメッセージ表示を削除してみましたが、
相変わらずButton.Clickが発生しない状況が続いています。
あんにんご さん
VB2008Expressですが、
プロジェクト作成、フォームにTabControl配置、TabPageそれぞれにTextboxとButtonを配置、
既存のコードを全て削除して、あんにんご さんのコードをPublic Class~End Classまで貼り付け。
実行→Textbox(TabPage1)マウスクリック→TabPage2マウスクリック<Validatingにより移動せず
→Button(TabPage1)マウスクリック<何も表示されず
となりました。
まったく同じコードで動作が異なると言うのは、環境の問題と捕らえるのが無難かと思い始めました・・・。 -
この例ですと、 e.Cancel = True の後に、MessageBox.Show("TextBox1 validating") などとメッセージボックス(またはモーダルダイアログ)を表示した場合など、質問者さんの現象が再現しないでしょうか?
↑なるほど、こうすると再現しました。(言語は VS2008 Express の C# で試しました。)ところが、画面とコードをいじってから、元に戻す作業(後から追加したコントロール削除とコードのコメント化)をおこなったら、また再現しなくなりました。(なぜだろう。。)ともかく aodus様とおなじと思われる現象を確認することはできましたが現象が出にくいという点では異なるようです。この現象の違いが環境の問題といわれれば、そうかもしれません。.NET のバージョンでいうと、.NET Framework 3.5 SP1 がインストールされています。ちなみにコードをどういじってみたかというと下記コードのとおり else 側でもメッセージ表示してみました。これだと、ボタンをクリックしたときに else 側を通った場合、フォーカスはボタンに移りますがボタンのクリックイベントは実行されませんでした。こうしてみると Validating 自体の実装には大変な苦労があるんだろうなと思いました(v v)private void textBox1_Validating(object sender, CancelEventArgs e){if (textBox1.Text == string.Empty){e.Cancel = true;MessageBox.Show("TextBox1 validating");}else{MessageBox.Show("TextBox1 else");}}以上、とりあえずご報告&etc.でした。- 回答としてマーク 高橋 春樹 2009年10月6日 9:16
-
VS2008(C#)で確認したところ、現象が再現できました。
(元々確認していた環境はVS2005(VB)でした。)
1.TabControl上に配置されたControlのValidatingイベントで、以下の処理を行う。
(1)Cancel=Trueとする
(2)MessageBoxなどのモーダルダイアログを表示する。
2.配置したControlにフォーカスがある状態で、TabPageを切り替える。
→ControlのValidatingイベントが発生する。
ダイアログが表示される。TabPageは替わらない。
3.この後、ControlのValidatingでCancel=Trueとならないようにする。
(今回の例ではTextBoxに何か入力する)
ValidatingでCancelされないのでButtonをクリックできるが、イベントは発生されない。
尚、Form上にComboBoxが配置されている場合、ドロップダウンの▼をマウスクリックすると、
一瞬リストが表示されるが、すぐに閉じてしまいます。- 回答としてマーク 高橋 春樹 2009年10月6日 9:16
-
1.TabControl上に配置されたControlのValidatingイベントで、以下の処理を行う。
↑この手順で繰り返し再現することが確認できました。
(1)Cancel=Trueとする
(2)MessageBoxなどのモーダルダイアログを表示する。
2.配置したControlにフォーカスがある状態で、TabPageを切り替える。
→ControlのValidatingイベントが発生する。
ダイアログが表示される。TabPageは替わらない。
3.この後、ControlのValidatingでCancel=Trueとならないようにする。
(今回の例ではTextBoxに何か入力する)
ValidatingでCancelされないのでButtonをクリックできるが、イベントは発生されない。
マウスダウン、アップイベントは起きるので回避策はとれそうですが…。- 回答としてマーク 高橋 春樹 2009年10月6日 9:16
-
細かいバージョンは分かりませんが、.NET FW 3.5 SP1が入っているPCでも、
入っていないPC(.NET FW 2.0まで)でも、手元の環境では今の所100%再現しています。
根本的な原因は分かりませんが、以下の処理でその場凌ぎはできそうなので何とかしてみます。
(1)Textbox.Validating発生時チェックがパスできない時、以下a,bの分岐を行う
(1.a)ActiveControlがTabControlで無い場合はe.Cancel=True、
(1.b)ActiveControlがTabControlである場合はe.Cancel=Trueを行わず、
フォーカスをsenderに合わせてTab移動不可フラグをTrue、
(2)TabContorl.Deselecting発生時にTab移動不可フラグがTrueならe.Cancel=True
相談に乗っていただき、誠にありがとうございました。- 回答としてマーク 高橋 春樹 2009年10月6日 9:16
-
こんにちは。フォーラムオペレーターの高橋春樹です。
あんにんごさん、kanepomさん、Jittaさん
ご投稿ありがとうございました。aodusさん、初めまして。
MSDNフォーラムのご利用ありがとうございます。なんとか回避策が見つかってよかったです。
Validatingイベントハンドラ内の、モーダルダイアログの表示を ErrorProviderを使用して表示させる方法でも回避できるようですね。今回、あんにんごさん、kanepomさん、Jittaさんからの投稿が有用なものだと思いましたので、勝手ながら、回答マークを付けさせて頂きました。
不適切と思いましたら、回答マークを削除することも可能です。今後ともMSDNフォーラムをよろしくお願いします(^-^)
マイクロソフト株式会社 フォーラム オペレーター 高橋春樹