以前、テキストボックスコントロールを基底クラスとして、入力される文字を数字のみとするクラスを紹介しました。
⇒テキストボックスの入力を数字のみにする方法
今回は、入力が便利になる様なプロパティを追加してみたいと思います。
追加する機能は、以下の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キーを押下することで、フォーカスが順次移動し、背景が黄色になります。 テキストボックス内に文字列が入力されていれば、フォーカス移動時には選択状態になります。
関連する記事
⇒テキストボックスの入力を数字のみにする方法その2(電卓の様な入力)⇒テキストボックスの Leave イベントでのエラー処理でフォーカス強制移動する方法について
コメント