MaskedTextBox かぁ~。VB6 のときもあるのは知ってたんですが、使ったこと無かったなぁ。
もっぱら グレープシティさんの InputMan にお世話になっていました。
.NET 2.0 の MaskedTextBox はもちろん初めてです。
たくさんプロパティがありますねー。
でも、内部で System.ComponentModel.MaskedTextProvider を作るための材料ばっかしだなぁとも感じました。
PromptChar には Nothing がセットできないのですね。よく考えればあたりまえか。
■参考文献
MaskedTextBox コントロール (Windows フォーム)
MaskedTextBox クラス
■実行画像
プロパティを変えてちょっと遊んでみた

Public Class MaskedTextBoxTest
Private m_MaskedTextBox As MaskedTextBox
Private Sub MaskedTextBoxTest_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Size = New Size(400, 400)
'' SplitContainer を配置
Dim split As SplitContainer = New SplitContainer()
With split
.Dock = DockStyle.Fill
.Size = New Size(Me.Width, Me.Height)
.Orientation = Orientation.Horizontal
.SplitterDistance = 350
.BorderStyle = BorderStyle.Fixed3D
.Panel1.AutoScroll = True
.Panel2.AutoScroll = True
End With
Me.Controls.Add(split)
'' MaskedTextBox を配置
Me.m_MaskedTextBox = New MaskedTextBox()
Me.m_MaskedTextBox.Name = "m_MaskedTextBox"
Me.m_MaskedTextBox.Location = New Point(5, 10)
AddHandler Me.m_MaskedTextBox.MaskInputRejected, AddressOf MaskInputRejected
split.Panel2.Controls.Add(Me.m_MaskedTextBox)
'' Button を配置
Dim btn As Button = New Button()
btn.Text = "Test"
btn.Location = New Point(180, 10)
AddHandler btn.Click, AddressOf ButonClicked
split.Panel2.Controls.Add(btn)
Dim tip As ToolTip = New ToolTip
Dim checkControls As List(Of CheckBox) = New List(Of CheckBox)
'' 以下、MaskedTextBox のプロパティをいじるコントロールを配置
' AllowPromptAsInput
Dim chkAllowPromptAsInput As CheckBox = New CheckBox()
chkAllowPromptAsInput.Text = "AllowPromptAsInput"
chkAllowPromptAsInput.Checked = Me.m_MaskedTextBox.AllowPromptAsInput
tip.SetToolTip(chkAllowPromptAsInput, "PromptChar を入力できるかどうか")
checkControls.Add(chkAllowPromptAsInput)
' AsciiOnly
Dim chkAsciiOnly As CheckBox = New CheckBox()
chkAsciiOnly.Text = "AsciiOnly"
chkAsciiOnly.Checked = Me.m_MaskedTextBox.AsciiOnly
tip.SetToolTip(chkAsciiOnly, "入力を a-z,A-Z のみにするか否か")
checkControls.Add(chkAsciiOnly)
' BeepOnError
Dim chkBeepOnError As CheckBox = New CheckBox()
chkBeepOnError.Text = "BeepOnError"
chkBeepOnError.Checked = Me.m_MaskedTextBox.BeepOnError
tip.SetToolTip(chkBeepOnError, "無効な入力の時に Beep するか否か")
checkControls.Add(chkBeepOnError)
' HidePromptOnLeave
Dim chkHidePromptOnLeave As CheckBox = New CheckBox()
chkHidePromptOnLeave.Text = "HidePromptOnLeave"
chkHidePromptOnLeave.Checked = Me.m_MaskedTextBox.HidePromptOnLeave
tip.SetToolTip(chkHidePromptOnLeave, "Leave 時にプロンプト文字を非表示にするか否か")
checkControls.Add(chkHidePromptOnLeave)
' ReadOnly
Dim chkReadOnly As CheckBox = New CheckBox()
chkReadOnly.Text = "ReadOnly"
chkReadOnly.Checked = Me.m_MaskedTextBox.ReadOnly
tip.SetToolTip(chkReadOnly, "読み取り専用にするか否か")
checkControls.Add(chkReadOnly)
' RejectInputOnFirstFailure
Dim chkRejectInputOnFirstFailure As CheckBox = New CheckBox()
chkRejectInputOnFirstFailure.Text = "RejectInputOnFirstFailure"
chkRejectInputOnFirstFailure.Checked = Me.m_MaskedTextBox.RejectInputOnFirstFailure
tip.SetToolTip(chkRejectInputOnFirstFailure, "コピペ等で一回で入力された時、最初の文字でエラーがあった場合そこで検証を停止するか、後続の文字も続けるか")
checkControls.Add(chkRejectInputOnFirstFailure)
' ResetOnPrompt
' AllowPrompt との関係は以下を参照
' http://msdn2.microsoft.com/ja-jp/library/system.windows.forms.maskedtextbox.resetonprompt(VS.80).aspx
Dim chkResetOnPrompt As CheckBox = New CheckBox()
chkResetOnPrompt.Text = "ResetOnPrompt"
chkResetOnPrompt.Checked = Me.m_MaskedTextBox.ResetOnPrompt
tip.SetToolTip(chkResetOnPrompt, "入力されたプロンプト文字によって、マスク内の現在の編集可能な位置がリセットされるか否か")
checkControls.Add(chkResetOnPrompt)
' ResetOnSpace
Dim chkResetOnSpace As CheckBox = New CheckBox()
chkResetOnSpace.Text = "ResetOnSpace"
chkResetOnSpace.Checked = Me.m_MaskedTextBox.ResetOnSpace
tip.SetToolTip(chkResetOnSpace, "入力された空白文字によって、マスク内の現在の編集可能な位置がリセットされるか否か")
checkControls.Add(chkResetOnSpace)
' SkipLiterals
Dim chkSkipLiterals As CheckBox = New CheckBox()
chkSkipLiterals.Text = "SkipLiterals"
chkSkipLiterals.Checked = Me.m_MaskedTextBox.SkipLiterals
tip.SetToolTip(chkSkipLiterals, "カーソルがプロンプト文字になった時に、次の編集可能文字へ移動しないか否か")
checkControls.Add(chkSkipLiterals)
' UseSystemPasswordChar
' PasswordChar よりも優先される
Dim chkUseSystemPasswordChar As CheckBox = New CheckBox()
chkUseSystemPasswordChar.Text = "UseSystemPasswordChar"
chkUseSystemPasswordChar.Checked = Me.m_MaskedTextBox.UseSystemPasswordChar
tip.SetToolTip(chkUseSystemPasswordChar, "OS のパスワード文字を使用するか否か")
checkControls.Add(chkUseSystemPasswordChar)
Dim otherControls As List(Of UserControl) = New List(Of UserControl)
' Mask
' 詳細は以下参照
' http://msdn2.microsoft.com/ja-jp/library/system.windows.forms.maskedtextbox.mask(VS.80).aspx
Dim txtMask As TextAndLabelUC = New TextAndLabelUC()
txtMask.Text = "Mask"
tip.SetToolTip(txtMask.TextBox1, "マスク文字列")
txtMask.TextBox1.Text = Me.m_MaskedTextBox.Mask
otherControls.Add(txtMask)
' PasswordChar
' PromptChar と同じだと InvalidOperationException が発生する
Dim txtPasswordChar As TextAndLabelUC = New TextAndLabelUC()
txtPasswordChar.Text = "PasswordChar"
With txtPasswordChar.TextBox1
.MaxLength = 1
.ShortcutsEnabled = False
.ImeMode = Windows.Forms.ImeMode.Disable
End With
tip.SetToolTip(txtPasswordChar.TextBox1, "パスワード文字")
txtPasswordChar.TextBox1.Text = Me.m_MaskedTextBox.PasswordChar
otherControls.Add(txtPasswordChar)
' PromptChar
' PasswordChar と同じだと InvalidOperationException が発生する
Dim txtPromptChar As TextAndLabelUC = New TextAndLabelUC()
txtPromptChar.Text = "PromptChar"
With txtPromptChar.TextBox1
.MaxLength = 1
.ShortcutsEnabled = False
.ImeMode = Windows.Forms.ImeMode.Disable
End With
tip.SetToolTip(txtPromptChar.TextBox1, "プロンプト文字")
txtPromptChar.TextBox1.Text = Me.m_MaskedTextBox.PromptChar
otherControls.Add(txtPromptChar)
' CutCopyMaskFormat
Dim cmbCutCopyMaskFormat As ComboAndLabelUC = New ComboAndLabelUC()
cmbCutCopyMaskFormat.Text = "CutCopyMaskFormat"
With cmbCutCopyMaskFormat.ComboBox1.Items
.Add(MaskFormat.ExcludePromptAndLiterals) ' ユーザーが入力した文字のみ
.Add(MaskFormat.IncludeLiterals) ' ユーザーが入力した文字+マスク文字
.Add(MaskFormat.IncludePrompt) ' ユーザーが入力した文字+プロンプト文字
.Add(MaskFormat.IncludePromptAndLiterals) ' ユーザーが入力した文字+マスク文字+プロンプト文字
End With
tip.SetToolTip(cmbCutCopyMaskFormat.ComboBox1, "コピーした時にどこまで含むか")
cmbCutCopyMaskFormat.ComboBox1.SelectedItem = Me.m_MaskedTextBox.CutCopyMaskFormat
otherControls.Add(cmbCutCopyMaskFormat)
' InsertKeyMode テキスト挿入モード
' InsertKeyMode 列挙体
' http://msdn2.microsoft.com/ja-jp/library/system.windows.forms.insertkeymode(VS.80).aspx
Dim cmbInsertKeyMode As ComboAndLabelUC = New ComboAndLabelUC()
cmbInsertKeyMode.Text = "InsertKeyMode"
With cmbInsertKeyMode.ComboBox1.Items
.Add(InsertKeyMode.Default) ' Ins キーの状態による
.Add(InsertKeyMode.Insert) ' Ins キー 関係なく挿入モード
.Add(InsertKeyMode.Overwrite) ' Ins キー 関係なく上書モード
End With
tip.SetToolTip(cmbInsertKeyMode.ComboBox1, "テキスト挿入モード")
cmbInsertKeyMode.ComboBox1.SelectedItem = Me.m_MaskedTextBox.InsertKeyMode
otherControls.Add(cmbInsertKeyMode)
' TextMaskFormat
Dim cmbTextMaskFormat As ComboAndLabelUC = New ComboAndLabelUC()
cmbTextMaskFormat.Text = "TextMaskFormat"
With cmbTextMaskFormat.ComboBox1.Items
.Add(MaskFormat.ExcludePromptAndLiterals) ' ユーザーが入力した文字のみ
.Add(MaskFormat.IncludeLiterals) ' ユーザーが入力した文字+マスク文字
.Add(MaskFormat.IncludePrompt) ' ユーザーが入力した文字+プロンプト文字
.Add(MaskFormat.IncludePromptAndLiterals) ' ユーザーが入力した文字+マスク文字+プロンプト文字
End With
tip.SetToolTip(cmbTextMaskFormat.ComboBox1, "Text プロパティにどこまで含むか")
cmbTextMaskFormat.ComboBox1.SelectedItem = Me.m_MaskedTextBox.TextMaskFormat
otherControls.Add(cmbTextMaskFormat)
' ValidatingType
Dim cmbValidatingType As ComboAndLabelUC = New ComboAndLabelUC()
cmbValidatingType.Text = "ValidatingType"
With cmbValidatingType.ComboBox1.Items
.Add(GetType(String))
.Add(GetType(Integer))
.Add(GetType(Long))
.Add(GetType(DateTime))
End With
tip.SetToolTip(cmbValidatingType.ComboBox1, "検証されるデータ型を指定")
cmbValidatingType.ComboBox1.SelectedItem = Me.m_MaskedTextBox.ValidatingType
otherControls.Add(cmbValidatingType)
For index As Integer = 0 To checkControls.Count - 1
Dim chk As CheckBox = checkControls(index)
AddHandler chk.CheckedChanged, AddressOf CheckedChanged
chk.AutoSize = True
chk.Location = New Point(10, 10 + index * 25)
split.Panel1.Controls.Add(chk)
Next
For index As Integer = 0 To otherControls.Count - 1
Dim ctrl As UserControl = otherControls(index)
If TypeOf ctrl Is ComboAndLabelUC Then
AddHandler DirectCast(ctrl, ComboAndLabelUC).ComboBox1.SelectedIndexChanged, AddressOf SelectedIndexChanged
ElseIf TypeOf ctrl Is TextAndLabelUC Then
AddHandler DirectCast(ctrl, TextAndLabelUC).TextBox1.Leave, AddressOf TextBoxLeave
End If
ctrl.Location = New Point(180, 10 + index * 40)
split.Panel1.Controls.Add(ctrl)
Next
End Sub
' CheckBox の値をプロパティに
Private Sub CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Dim chk As CheckBox = DirectCast(sender, CheckBox)
Dim ret As Object = Me.SetProperty(chk.Text, chk.Checked)
chk.Checked = CBool(ret)
End Sub
' ComboBox の値をプロパティに
Private Sub SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Dim cmb As ComboBox = DirectCast(sender, ComboBox)
Dim ret As Object = Me.SetProperty(DirectCast(cmb.Parent, ComboAndLabelUC).Text, cmb.SelectedItem)
cmb.SelectedItem = ret
End Sub
' TextBox の値をプロパティに
Private Sub TextBoxLeave(ByVal sender As Object, ByVal e As System.EventArgs)
Dim tBox As TextBox = DirectCast(sender, TextBox)
Dim ret As Object = Me.SetProperty(DirectCast(tBox.Parent, TextAndLabelUC).Text, tBox.Text)
tBox.Text = CStr(ret)
End Sub
Private Function SetProperty(ByVal propName As String, ByVal propValue As Object) As Object
Dim maskType As Type = Me.m_MaskedTextBox.GetType()
Dim props As System.Reflection.PropertyInfo() = _
maskType.GetProperties()
For Each prop As System.Reflection.PropertyInfo In props
If prop.Name = propName Then
If prop.PropertyType Is GetType(System.Char) Then
Try
prop.SetValue(Me.m_MaskedTextBox, CChar(propValue), Nothing)
Catch ex As System.Reflection.TargetInvocationException
If Not ex.InnerException Is Nothing AndAlso TypeOf ex.InnerException Is ArgumentException Then
MessageBox.Show(prop.Name & ":" & ex.InnerException.Message)
' デフォルトの値を代入する
prop.SetValue(Me.m_MaskedTextBox, "_"c, Nothing)
Else
MessageBox.Show(prop.Name & ":" & ex.Message)
End If
Return "_"c
End Try
Else
prop.SetValue(Me.m_MaskedTextBox, propValue, Nothing)
End If
Return propValue
End If
Next
Return Nothing
End Function
' ユーザーの入力または割り当てられた文字が、入力マスクの対応する書式要素と一致しない場合に発生
Private Sub MaskInputRejected(ByVal sender As Object, ByVal e As MaskInputRejectedEventArgs)
Dim masked As MaskedTextBox = DirectCast(sender, MaskedTextBox)
Console.WriteLine("MaskedTextBox.Name:" & masked.Name)
Console.WriteLine("MaskedTextBox.Mask:" & masked.Mask)
Console.WriteLine("MaskedTextBox.Text:" & masked.Text)
' e.RejectionHint については、MaskedTextResultHint 列挙体 参照
' http://msdn2.microsoft.com/ja-jp/library/system.componentmodel.maskedtextresulthint(VS.80).aspx
Console.WriteLine("e.RejectionHint:" & e.RejectionHint.ToString())
End Sub
Private Sub ButonClicked(ByVal sender As Object, ByVal e As System.EventArgs)
' MaskCompleted
' 必須の入力がすべて入力マスクに入力されたかどうかを示す
Console.WriteLine("MaskCompleted:" & Me.m_MaskedTextBox.MaskCompleted.ToString())
' MaskedTextProvider
' Mask、AllowPromptAsInput、AsciiOnly、Culture などにより内部で自動生成
' またはコンストラクタの引数にMaskedTextProvider オブジェクトを指定してやることにより
' セット可能。
Dim provider As System.ComponentModel.MaskedTextProvider = Me.m_MaskedTextBox.MaskedTextProvider
Console.WriteLine("MaskedTextProvider.IncludeLiterals:" & provider.IncludeLiterals.ToString())
' SelectedText
' 選択されている文字列(CutCopyMaskFormat に依存する)
Console.WriteLine("SelectedText:" & Me.m_MaskedTextBox.SelectedText)
' ValidatingType プロパティで指定された型の Object
' 失敗した場合は Nothing
Dim o As Object = Me.m_MaskedTextBox.ValidateText()
If Not o Is Nothing Then
Console.WriteLine("ValidateText:" & o.ToString())
End If
End Sub
End Class
'' 以下はどうでもいいユーザーコントロール
' Label と TextBox があるだけの UserControl
Public Class TextAndLabelUC
Public Shadows Property Text() As String
Get
Return Me.Label1.Text
End Get
Set(ByVal value As String)
Me.Label1.Text = value
End Set
End Property
End Class
' Label と ComboBox があるだけの UserControl
Public Class ComboAndLabelUC
Public Sub New()
' この呼び出しは、Windows フォーム デザイナで必要です。
InitializeComponent()
' InitializeComponent() 呼び出しの後で初期化を追加します。
Me.ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList
End Sub
Public Shadows Property Text() As String
Get
Return Me.Label1.Text
End Get
Set(ByVal value As String)
Me.Label1.Text = value
End Set
End Property
End Class