タブページについて への返答
投稿で使用できる特殊コードの説明。(別タブで開きます。)
以下の返答は逆順(新しい順)に並んでいます。
投稿者 るしぇ  ()
投稿日時
2008/8/12 21:18:00
Private Sub TabPage_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) _
Handles TabPage1.Validating, TabPage2.Validating
''※注 Validating イベントをキャンセルするので下のコードでは対応できない
''▼Formを閉じるときにはイベントが発生しないようにする
'If ActiveControl.CausesValidation = False Then
' Exit Sub
'End If
Dim targetTab As TabPage
targetTab = DirectCast(sender, TabPage)
'▼検証中の TabPage の全てのコントロールに対し、TextBox であれば入力チェック
For Each t As Control In targetTab.Controls
If TypeOf t Is TextBox AndAlso 自作メソッド(t.Text) = False Then
e.Cancel = True
't.Focus()
DirectCast(t, TextBox).SelectAll()
Exit Sub
End If
Next
End Sub
'■自作メソッド
''' <summary>指定した値が正しいかチェックする</summary>
''' <param name="Expression">チェックしたい文字列型の値</param>
''' <returns>正しければTrueを返し、エラーならメッセージを表示してFalseを返す</returns>
Private Function 自作メソッド(ByVal Expression As String) As Boolean
Dim reg As New System.Text.RegularExpressions.Regex("^\d{1,3}$")
If Not reg.IsMatch(Expression) Then
MsgBox("error", vbCritical, "入力エラー")
'TabControl1.SelectedIndex = 0
Return False
End If
If CInt(Expression) > 300 Then
MsgBox("300over", vbCritical, "入力エラー")
'TabControl1.SelectedIndex = 0
Return False
End If
Return True
End Function
Handles TabPage1.Validating, TabPage2.Validating
''※注 Validating イベントをキャンセルするので下のコードでは対応できない
''▼Formを閉じるときにはイベントが発生しないようにする
'If ActiveControl.CausesValidation = False Then
' Exit Sub
'End If
Dim targetTab As TabPage
targetTab = DirectCast(sender, TabPage)
'▼検証中の TabPage の全てのコントロールに対し、TextBox であれば入力チェック
For Each t As Control In targetTab.Controls
If TypeOf t Is TextBox AndAlso 自作メソッド(t.Text) = False Then
e.Cancel = True
't.Focus()
DirectCast(t, TextBox).SelectAll()
Exit Sub
End If
Next
End Sub
'■自作メソッド
''' <summary>指定した値が正しいかチェックする</summary>
''' <param name="Expression">チェックしたい文字列型の値</param>
''' <returns>正しければTrueを返し、エラーならメッセージを表示してFalseを返す</returns>
Private Function 自作メソッド(ByVal Expression As String) As Boolean
Dim reg As New System.Text.RegularExpressions.Regex("^\d{1,3}$")
If Not reg.IsMatch(Expression) Then
MsgBox("error", vbCritical, "入力エラー")
'TabControl1.SelectedIndex = 0
Return False
End If
If CInt(Expression) > 300 Then
MsgBox("300over", vbCritical, "入力エラー")
'TabControl1.SelectedIndex = 0
Return False
End If
Return True
End Function
投稿者 るしぇ  ()
投稿日時
2008/8/12 21:17:00
>>5
>また、このコードだとFocusのところでValidatingイベントが
>発生してしまい、メッセージが2回表示されてしまいます。
Validating 使うときは e.Cancel を使うべきと思うんだけど、検証イベントから
抜ける手段を用意しないと Form を閉じることができませんね。
# まぁ、検証イベントをクリアしてないんだから、正しい動きでもあるんでしょうが。
そうなってくると一度検証したテキストボックスについては Text が変更されるまで
再検証しないようなコードも欲しくなってきます。。。ところが、ここで複数の
テキストボックスがあるとフラグも複数必要?。。。と深みにハマってくのでボクは
Validating が嫌いですww
初心者は前回選択されていたタブを変数に覚えてて、TabControl1.SelectedIndexChanged
使うほうが簡単かも?ま、とりあえずボクは Validating を使いこなせてないので、1つの
案だけにとどめます。
>また、このコードだとFocusのところでValidatingイベントが
>発生してしまい、メッセージが2回表示されてしまいます。
Validating 使うときは e.Cancel を使うべきと思うんだけど、検証イベントから
抜ける手段を用意しないと Form を閉じることができませんね。
# まぁ、検証イベントをクリアしてないんだから、正しい動きでもあるんでしょうが。
そうなってくると一度検証したテキストボックスについては Text が変更されるまで
再検証しないようなコードも欲しくなってきます。。。ところが、ここで複数の
テキストボックスがあるとフラグも複数必要?。。。と深みにハマってくのでボクは
Validating が嫌いですww
初心者は前回選択されていたタブを変数に覚えてて、TabControl1.SelectedIndexChanged
使うほうが簡単かも?ま、とりあえずボクは Validating を使いこなせてないので、1つの
案だけにとどめます。
投稿者 鍵  ()
投稿日時
2008/8/12 18:54:00
Private Sub TabPage1_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles TabPage1.Validating
'▼Formを閉じるときにはイベントが発生しないようにする
If ActiveControl.CausesValidation = False Then
Exit Sub
End If
'▼TabPage1の全てのコントロールに対し、入力チェック
For Each t As TextBox In TabPage1.Controls
If 自作メソッド(t.Text) = False Then
t.Focus()
t.SelectAll()
Exit Sub
End If
Next
End Sub
'■自作メソッド
''' <summary>指定した値が正しいかチェックする</summary>
''' <param name="Expression">チェックしたい文字列型の値</param>
''' <returns>正しければTrueを返し、エラーならメッセージを表示してFalseを返す</returns>
Private Function 自作メソッド(ByVal Expression As String) As Boolean
Dim reg As New System.Text.RegularExpressions.Regex("^\d{1,3}$")
If Not reg.IsMatch(Expression) Then
MsgBox("error", vbCritical, "入力エラー")
TabControl1.SelectedIndex = 0
Return False
End If
If CInt(Expression) > 300 Then
MsgBox("300over", vbCritical, "入力エラー")
TabControl1.SelectedIndex = 0
Return False
End If
Return True
End Function
入力チェックならエラーのときはテキストを初期化する
より、全て選択したほうが親切かと思い、SelectAllを
使用しています。
また、このコードだとFocusのところでValidatingイベントが
発生してしまい、メッセージが2回表示されてしまいます。
他に方法はないものでしょうか・・・・・
他の方のフォローに期待します^^;
'▼Formを閉じるときにはイベントが発生しないようにする
If ActiveControl.CausesValidation = False Then
Exit Sub
End If
'▼TabPage1の全てのコントロールに対し、入力チェック
For Each t As TextBox In TabPage1.Controls
If 自作メソッド(t.Text) = False Then
t.Focus()
t.SelectAll()
Exit Sub
End If
Next
End Sub
'■自作メソッド
''' <summary>指定した値が正しいかチェックする</summary>
''' <param name="Expression">チェックしたい文字列型の値</param>
''' <returns>正しければTrueを返し、エラーならメッセージを表示してFalseを返す</returns>
Private Function 自作メソッド(ByVal Expression As String) As Boolean
Dim reg As New System.Text.RegularExpressions.Regex("^\d{1,3}$")
If Not reg.IsMatch(Expression) Then
MsgBox("error", vbCritical, "入力エラー")
TabControl1.SelectedIndex = 0
Return False
End If
If CInt(Expression) > 300 Then
MsgBox("300over", vbCritical, "入力エラー")
TabControl1.SelectedIndex = 0
Return False
End If
Return True
End Function
入力チェックならエラーのときはテキストを初期化する
より、全て選択したほうが親切かと思い、SelectAllを
使用しています。
また、このコードだとFocusのところでValidatingイベントが
発生してしまい、メッセージが2回表示されてしまいます。
他に方法はないものでしょうか・・・・・
他の方のフォローに期待します^^;
投稿者 鍵  ()
投稿日時
2008/8/12 18:52:00
>サンプルプログラムとして、タブページ2つに、
>各タブページの中にTextBoxが2つずつある画面で
↑のことからTextBox2もTabPage1上に存在するものだと
解釈しました。
>そうはせずに、処理を纏めて、プロシージャに呼び出す?方法があると聞きました。
処理を纏めて、プロシージャに呼び出すというのは
よく分かりませんでした、未熟ですみません。
処理を纏めたメソッドを自作するということでしょうか?
とりあえず入力チェックしてエラーならFocusを戻す。
というコードを考えてみました。
イベントをValidatingに変更してあります。
また、Formを閉じるときにもチェックがかかってしまう
のでFormのCausesValidationプロパティをFalseにして
おいてください。
長くなるのでコード部分は分けて投稿します。
>各タブページの中にTextBoxが2つずつある画面で
↑のことからTextBox2もTabPage1上に存在するものだと
解釈しました。
>そうはせずに、処理を纏めて、プロシージャに呼び出す?方法があると聞きました。
処理を纏めて、プロシージャに呼び出すというのは
よく分かりませんでした、未熟ですみません。
処理を纏めたメソッドを自作するということでしょうか?
とりあえず入力チェックしてエラーならFocusを戻す。
というコードを考えてみました。
イベントをValidatingに変更してあります。
また、Formを閉じるときにもチェックがかかってしまう
のでFormのCausesValidationプロパティをFalseにして
おいてください。
長くなるのでコード部分は分けて投稿します。
投稿者 らるきー  ()
投稿日時
2008/8/11 21:11:00
>>1 鍵さん
お返事ありがとうございます!
VB2005を使用しています。
変な日本語で申し訳なかったですが、アドバイス頂いた様にしてみるとできました↓
サンプルプログラムとして、タブページ2つに、各タブページの中にTextBoxが2つずつある画面で
Dim i, p, x, y As Integer
Private Sub TabPage1_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TabPage1.Leave
'正規表現で入力された値を判断する。
If Regex.IsMatch(TextBox1.Text, "^[0-9]{1,3}$") Then
i = Val(TextBox1.Text)
i = Convert.ToInt32(i)
Else
MsgBox("textbox1 error", vbCritical, "入力エラー")
TextBox1.Clear()
Exit Sub
End If
Me.TextBox1.Focus()
If i > 300 Then
MsgBox("300overr", vbCritical, "入力エラー")
TextBox1.Clear()
Exit Sub
End If
Me.TextBox1.Focus()
End Sub
これでtabpage1のTextBox1に入力された数値を、TabPage1以外のTabPageに移ろうとしたときに、
判断できるようになりましたが。。
>たとえば、[OK]ボタンがクリックされたときにまだ必要な項目、たとえばメールアドレスが入力されていなかったとします。
>この場合にただ単に「メールアドレスを入力してください。」という警告のメッセージを表示するだけではなく、
>そのメッセージとともに自動的にメールアドレス欄がフォーカス状態になるならば、
>それは親切なアプリケーションと言えます。
とこちらのサイトでも仰られている様に、エラーがあった箇所にフォーカスを戻したいのですが
↑のプログラムではTabPage1以外に移った場合、そのTabPageのTextBoxにフォーカスが移ってしまいます。。
何とかTabPage1に戻って、エラーのあるTextBoxにフォーカスを戻す方法はないでしょうか?
それともう1つなのですが、↑のプログラムはTabPage1のTextBox1の処理なのですが
もう1つTextBox2にも同じ処理をさせたいので、コピーすれば早いのですが。。
そうはせずに、処理を纏めて、プロシージャに呼び出す?方法があると聞きました。
なにぶん初心者でよくわかっていないのですが、そちらの方法もご教授いただければと思います。
長々と本当にすみません!
お返事ありがとうございます!
VB2005を使用しています。
変な日本語で申し訳なかったですが、アドバイス頂いた様にしてみるとできました↓
サンプルプログラムとして、タブページ2つに、各タブページの中にTextBoxが2つずつある画面で
Dim i, p, x, y As Integer
Private Sub TabPage1_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TabPage1.Leave
'正規表現で入力された値を判断する。
If Regex.IsMatch(TextBox1.Text, "^[0-9]{1,3}$") Then
i = Val(TextBox1.Text)
i = Convert.ToInt32(i)
Else
MsgBox("textbox1 error", vbCritical, "入力エラー")
TextBox1.Clear()
Exit Sub
End If
Me.TextBox1.Focus()
If i > 300 Then
MsgBox("300overr", vbCritical, "入力エラー")
TextBox1.Clear()
Exit Sub
End If
Me.TextBox1.Focus()
End Sub
これでtabpage1のTextBox1に入力された数値を、TabPage1以外のTabPageに移ろうとしたときに、
判断できるようになりましたが。。
>たとえば、[OK]ボタンがクリックされたときにまだ必要な項目、たとえばメールアドレスが入力されていなかったとします。
>この場合にただ単に「メールアドレスを入力してください。」という警告のメッセージを表示するだけではなく、
>そのメッセージとともに自動的にメールアドレス欄がフォーカス状態になるならば、
>それは親切なアプリケーションと言えます。
とこちらのサイトでも仰られている様に、エラーがあった箇所にフォーカスを戻したいのですが
↑のプログラムではTabPage1以外に移った場合、そのTabPageのTextBoxにフォーカスが移ってしまいます。。
何とかTabPage1に戻って、エラーのあるTextBoxにフォーカスを戻す方法はないでしょうか?
それともう1つなのですが、↑のプログラムはTabPage1のTextBox1の処理なのですが
もう1つTextBox2にも同じ処理をさせたいので、コピーすれば早いのですが。。
そうはせずに、処理を纏めて、プロシージャに呼び出す?方法があると聞きました。
なにぶん初心者でよくわかっていないのですが、そちらの方法もご教授いただければと思います。
長々と本当にすみません!
投稿者 鍵  ()
投稿日時
2008/8/11 16:38:00
こんにちは。
問題の早期解決の為にも、VBのバージョンの明記を
お願いします。
とりあえず以下のように解釈しましたが、
よろしいでしょうか?
タブページ1~3にTextboxが1つずつ配置されている。
Buttonを押したときに表示されているページの
TextboxのTextが数字か判断する。
表示されているタブページが1でなくなったときに
Textbox1のTextが数字か判断する。
表示されているタブページはTabControl.SelectedIndexで
知ることができます。
また、数字かどうかはIsNumericで判断できます。
以下がコードです。(VB2008)で検証、動作確認。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Select Case TabControl1.SelectedIndex
Case 0
Judge(TextBox1.Text)
Case 1
Judge(TextBox2.Text)
Case 2
Judge(TextBox3.Text)
End Select
End Sub
Private Sub TabPage1_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TabPage1.Leave
Judge(TextBox1.Text)
End Sub
Private Sub Judge(ByVal Expression As String)
If IsNumeric(Expression) Then
'数字だったときの処理を書く
MsgBox("数字です")
Else
'数字ではないときの処理を書く
MsgBox("数字ではありません")
End If
End Sub
意図した動作でなかったらすみません。
問題の早期解決の為にも、VBのバージョンの明記を
お願いします。
とりあえず以下のように解釈しましたが、
よろしいでしょうか?
タブページ1~3にTextboxが1つずつ配置されている。
Buttonを押したときに表示されているページの
TextboxのTextが数字か判断する。
表示されているタブページが1でなくなったときに
Textbox1のTextが数字か判断する。
表示されているタブページはTabControl.SelectedIndexで
知ることができます。
また、数字かどうかはIsNumericで判断できます。
以下がコードです。(VB2008)で検証、動作確認。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Select Case TabControl1.SelectedIndex
Case 0
Judge(TextBox1.Text)
Case 1
Judge(TextBox2.Text)
Case 2
Judge(TextBox3.Text)
End Select
End Sub
Private Sub TabPage1_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TabPage1.Leave
Judge(TextBox1.Text)
End Sub
Private Sub Judge(ByVal Expression As String)
If IsNumeric(Expression) Then
'数字だったときの処理を書く
MsgBox("数字です")
Else
'数字ではないときの処理を書く
MsgBox("数字ではありません")
End If
End Sub
意図した動作でなかったらすみません。
投稿者 らるきー  ()
投稿日時
2008/8/11 08:30:00
何やら掲示板が大変なこと?になっている時に失礼致します。。
2ヶ月ほど前からvb.netを触り始めた初心者です。
いつもこちらのサイトを参考にさせて頂いております。
現在タブページを使用したデザインのプログラムをしていますが、タブページ1~3に配意されたTextBoxの内容をボタンが押されたときに数字かどうかの判断をする処理を書いているのですが、
タブページ1に配置されたTextbox1の入力内容を、ほかのタブページに移動する際(タブページ2、または3を選択したとき)に処理の命令を出すようにしたいのです。
文章が下手で上手く伝わるかどうかわかりませんが
アドバイスよろしくお願いいたします><
2ヶ月ほど前からvb.netを触り始めた初心者です。
いつもこちらのサイトを参考にさせて頂いております。
現在タブページを使用したデザインのプログラムをしていますが、タブページ1~3に配意されたTextBoxの内容をボタンが押されたときに数字かどうかの判断をする処理を書いているのですが、
タブページ1に配置されたTextbox1の入力内容を、ほかのタブページに移動する際(タブページ2、または3を選択したとき)に処理の命令を出すようにしたいのです。
文章が下手で上手く伝わるかどうかわかりませんが
アドバイスよろしくお願いいたします><
SelectedIndexChangedなんてイベントがあったとは・・・
知りませんでした。
ValidatingやLeaveしか頭になかったのですが、
確かにこちらのほうが簡単かもしれませんね。