忍者ブログ

VB.NET-TIPS などプログラミングについて

VB.NETのTIPS(小技集)を中心に、その他のプログラミングについて少し役に立つ情報を発信します。いわゆる個人的な忘備録ですが、みなさんのお役に立てれば幸いです。

テキストボックス拡張クラスにプロパティを追加する方法

以前、テキストボックスコントロールを基底クラスとして、入力される文字を数字のみとするクラスを紹介しました。
テキストボックスの入力を数字のみにする方法

今回は、入力が便利になる様なプロパティを追加してみたいと思います。
追加する機能は、以下の3個の機能です。

  • 自分自身にフォーカス移動が在った場合に、背景色を変更する。
  • 自分自身にフォーカス移動が在った場合に、テキスト全体を選択状態にする。
  • Enter キーによる次のタブストップが指定されているコントロールへのフォーカス移動。

最初の背景色の設定の為に、自分自身がアクティブである時の背景色と、 アクティブではない時の背景色を設定するプロパティを設定します。
クラスの静的変数にアクティブ時(_ActiveBackColor)と非アクティブ時(_InactiveBackColor)の背景色を持ちます。 さらに、この変数をアクセスするためのプロパティ宣言をそれぞれ、ActiveBackColor InactiveBackColor とします。
背景色を変える処理を、Enterイベントの処理の OnEnter 及び、Leaveイベントの処理の OnLeave で処理を行います。

また、フォーカスが移動してきた時の、テキスト全体を選択状態にする指示プロパティを ActiveSelectAll として宣言します。
実際の処理は、 OnEnter 内でこのフラグを見て、 True の場合に、テキストの全選択を行います。

以下にソースを示します。

テキストボックス拡張クラスにプロパティを追加する方法

Public Class ClsNumTextBox2
    Inherits TextBox

    'アクティブ時の背景色
    Private _ActiveBackColor As Color = Color.White
    '非アクティブ時の背景色
    Private _InactiveBackColor As Color = Color.White
    'アクティブ時の全選択フラグ
    Private _ActiveSelectAll As Boolean = False

    'クリップボード貼付メッセージ
    Const WM_PASTE As Integer = &H302

    ''' 
    ''' WndProc メソッド (override)
    ''' 
    ''' <param name="m">メッセージ</param>
    Protected Overrides Sub WndProc(ByRef m As Message)
        Select Case m.Msg
            Case WM_PASTE
                Dim iDataObj As IDataObject = Clipboard.GetDataObject()
                'クリップボードの中身があるか、かつ文字列に変換できるか??
                If (iDataObj IsNot Nothing) And (iDataObj.GetDataPresent(DataFormats.Text) = True) Then
                    '文字列に変換
                    Dim strClip As String = DirectCast(iDataObj.GetData(DataFormats.Text), String)
                    '文字列が数字のみか調べる
                    If Me.ChkClipString(strClip) = False Then
                        Return
                    End If
                End If
        End Select

        'メッセージのデフォルト処理を呼出す
        MyBase.WndProc(m)
    End Sub

    ''' 
    ''' コンストラクタ
    ''' 
    Public Sub New()
        MyBase.New()
        'IMEを無効にする
        MyBase.ImeMode = ImeMode.Disable
    End Sub

    ''' 
    ''' アクティブ時の背景色
    ''' 
    Public Property ActiveBackColor As Color
        Set(value As Color)
            _ActiveBackColor = value   '退避値に設定
        End Set
        Get
            Return _ActiveBackColor    '退避値を返す
        End Get
    End Property

    ''' 
    ''' 非アクティブ時の背景色
    ''' 
    Public Property InactiveBackColor As Color
        Set(value As Color)
            _InactiveBackColor = value   '退避値に設定
        End Set
        Get
            Return _InactiveBackColor    '退避値を返す
        End Get
    End Property

    ''' 
    ''' アクティブ時の全選択フラグ
    ''' 
    Public Property ActiveSelectAll As Boolean
        Set(value As Boolean)
            _ActiveSelectAll = value   '退避値に設定
        End Set
        Get
            Return _ActiveSelectAll    '退避値を返す
        End Get
    End Property

    ''' 
    ''' Enterイベントの処理
    ''' 
    Protected Overrides Sub OnEnter(e As EventArgs)
        MyBase.OnEnter(e)
        '背景色の設定
        Me.BackColor = Me._ActiveBackColor
        'アクティブ時の全選択フラグ
        If Me._ActiveSelectAll = True Then
            Me.SelectAll()
        End If
    End Sub

    ''' 
    ''' Leaveイベントの処理
    ''' 
    Protected Overrides Sub OnLeave(e As EventArgs)
        MyBase.OnLeave(e)
        '背景色の設定
        Me.BackColor = Me._InactiveBackColor
    End Sub

    ''' 
    ''' KeyPressイベントの処理
    ''' 
    Protected Overrides Sub OnKeyPress(e As KeyPressEventArgs)
        MyBase.OnKeyPress(e)
        'キーが [0]~[9] または [BackSpace] 以外の場合イベントをキャンセル
        If Not (("0"c <= e.KeyChar And e.KeyChar <= "9"c) Or e.KeyChar = ControlChars.Back) Then
            e.Handled = True
        End If
    End Sub

    ''' 
    ''' 文字列のチェック関数
    ''' 
    ''' <param name="strClip">指定文字列</param>
    ''' True:OK, False:NG
    Private Function ChkClipString(ByVal strClip As String) As Boolean
        ChkClipString = False
        If System.Text.RegularExpressions.Regex.IsMatch(strClip, "^[0-9]+$") Then
            Return True
        End If
    End Function

    ''' 
    ''' KeyDownイベントの処理
    ''' 
    Protected Overrides Sub OnKeyDown(e As KeyEventArgs)
        MyBase.OnKeyDown(e)
        '[Enter]キーの場合
        If e.KeyCode = Keys.Enter Then
            If e.Control = False Then
                '[Ctrl]キーが押下されていない場合、自分の親のコントロールの次のフォーカスへ移動
                Me.Parent.SelectNextControl(Me, Not e.Shift, True, True, True)
            End If
        End If
    End Sub

End Class

このソースを別のファイルで作成し、一度コンパイルします。 そうすると、ツールボックスの中に ClsNumTextBox2 が現れますので、以下の様にこれをフォーム上に貼り付けます。
ActiveBackColor にはYellow InactiveBackColor にはWhite を設定し、 ActiveSelectAll にはTrue と設定します。

このフォームにはコードを何も記述していませんが、そのまま実行した結果は以下の様な感じです。
Enterキーを押下することで、フォーカスが順次移動し、背景が黄色になります。 テキストボックス内に文字列が入力されていれば、フォーカス移動時には選択状態になります。

PR

コメント

コメントを書く