投稿者 魔界の仮面弁士  (社会人) 投稿日時 2018/5/22 00:31:46
> For Each ctl As Control In Me.Controls
>  If TypeOf ctl Is TextBox  Then

この Form_Load 側のコードについては、
TypeOf 演算子の代わりに
OfType 拡張メソッドを使うと、スッキリ書けますよ。


> AddHandler CType(ctl, TextBox).Click, AddressOf TextBox_textbox_leave

最初の質問では Leave イベントを使っていましたよね。
今回は何故 Click イベントなのでしょうか?


> If Val(CType(sender,TextBox).Text) <= 0 Then 

Val は、常に数値変換に成功するとは限りませんので、
このようなケースで Val() を使うことはおすすめしません。

たとえば Val("1.2%") や Val("-5.2&") なら InvalidCastException を発しますし、
Val("32768%") や Val("1.8d308") なら OverflowException を発することになります。

代わりに、Integer.TryParse や Decimal.TryParse の利用を
検討してみてください。これなら例外になってしまうこともありません。


> MsgBox("0か負の値がはいっています")
> TextBox1.BackColor = Color.Red

上記だと、常に TextBox1 の色が変化してしまいます。
イベントハンドラの引数 sender には、そのイベントの対象となるコントロールが
セットされていますので、最初に rvf さんが書かれた通り、sender を活用しましょう。

それと上記の順だと、メッセージを閉じるまで色が変わらないので、
色を変えてからメッセージを出した方が良いかも知れません。
(画面構成によっては、メッセージの後で色を変えた方が良い場合もあるので、
 一概にどちらが良いとは言い切れませんが)


> TextBox1.BackColor = Color.White

色を戻すときには、Color.White をセットするのではなく、
Color.Empty をセットするか、または ResetBackColor メソッドを
呼び出すことをお勧めします。

背景色を変更していない TextBox を Enabled = False にした場合と
背景色を変更してから Enabled = False にした場合とを比べてみると
表示が異なってくることになります。
https://www.papy.in/bbs/vbnet/200901/09010020.html
https://social.msdn.microsoft.com/Forums/ja-JP/195fcbbe-8fe4-4b1e-aa1f-c9894238c81e/control?forum=netfxgeneralja



ということで修正案。


Option Strict Off
Public Class Form1
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        For Each txt In Me.Controls.OfType(Of TextBox)()
            AddHandler txt.Leave, AddressOf TextBoxes_Leave
        Next
    End Sub

    Private Sub TextBoxes_Leave(sender As TextBox, e As EventArgs)
        Dim d As Decimal
        If Decimal.TryParse(sender.Text, d) AndAlso d > 0.0d Then
            sender.ResetBackColor()
        Else
            'MsgBox("非数値、または 0 以下の値が入っています。") 
            sender.BackColor = Color.Red
            MsgBox("0 よりも大きい数値を入力してください。")
        End If
    End Sub
End Class