Книга: Программирование мобильных устройств на платформе .NET Compact Framework

Листинг 13.3. Фильтрующее текстовое окно, принимающее текст в формате ###-##-####

Листинг 13.3. Фильтрующее текстовое окно, принимающее текст в формате ###-##-####

Option Strict On
Imports System
'----------------------------------------------------------------------------
'Этот класс является элементом управления, производным от элемента управления
'TextBox.
'Он наследует все графические свойства TextBox, но добавляет фильтрацию
'содержимого текстового окна, тем самым гарантируя,
'что вводимый текст будет соответствовать формату:
'###-##-####.
'Этот формат соответствует формату номеров карточек социального страхования,
'используемых в США.
'-----------------------------------------------------------------------------
Public Class SocialSecurityTextBox
Inherits System.Windows.Forms.TextBox
Private m_inputIsFullValidEntry As Boolean
'------------------------------------------------
'Указывает, получен ли
'номер карточки социального страхования полностью
'------------------------------------------------
Public ReadOnly Property IsFullValidInput() As Boolean
 Get
  Return m_inputIsFullValidEntry
 End Get
End Property
'Объект StringBuilder, которую мы будем часто использовать
Private m_sb As System.Text.StringBuilder
'Максимальная длина обрабатываемых строк
Const SSNumberLength As Integer = 11
'-----------
'Конструктор
'-----------
Public Sub New()
 'Распределить память для нашего объекта StringBuilder и предоставить
 'место для нескольких дополнительных рабочих символов по умолчанию
 m_sb = New System.Text.StringBuilder(SSNumberLength + 5)
 m_inputIsFullValidEntry = False
End Sub
'---------------------------------------------------------------------
'Форматировать поступающий текст с целью установления его соответствия
'нужному формату:
'
' Формат номера карточки социального страхования: ###-##-####
' символы: 01234567890
'
' [in] inString          : Текст, который мы хотим форматировать
' [in/out] selectionStart: Текущая точка вставки в тексте;
'  она будет смещаться в связи с удалением
'                           и добавлением нами символов
'----------------------------------------------------------------------
Private Function formatText_NNN_NN_NNNN(ByVal inString As _
 String, ByRef selectionStart As Integer) As String
 Const firstDashIndex As Integer = 3
 Const secondDashIndex As Integer = 6
 'Удалить старые данные и поместить входную строку
 'в объект StringBuilder, чтобы мы могли с ней работать.
 m_sb.Length = 0
 m_sb.Append(inString)
 '------------------------------------------------------------
 'Просмотреть каждый символ в строке, пока не будет
 'достигнута максимальная длина нашего форматированного текста
 '------------------------------------------------------------
 Dim currentCharIndex As Integer
 currentCharIndex = 0
 While ((currentCharIndex < m_sb.Length) AndAlso _
  (currentCharIndex < SSNumberLength))
  Dim currentChar As Char
  currentChar = m_sb(currentCharIndex)
  If ((currentCharIndex = firstDashIndex) OrElse _
   (currentCharIndex = secondDashIndex)) Then
   '-------------------------------
   'The character needs to be a "-"
   '-------------------------------
   If (currentChar <> "-"c) Then 'Вставить дефис
    m_sb.Insert(currentCharIndex, "-")
    'Если мы добавили символ перед точкой вставки,
    'она должна быть смещена вперед
    If (currentCharIndex <= selectionStart) Then
     selectionStart = selectionStart + 1
    End If
   End If
   'Этот символ годится, перейти к следующему символу
   currentCharIndex = currentCharIndex + 1
  Else
   '-------------------------
   'Символ должен быть цифрой
   '-------------------------
   If (System.Char.IsDigit(currentChar) = False) Then
    'Удалить символ
    m_sb.Remove(currentCharIndex, 1)
    'Если мы добавили символ перед точкой вставки,
    'она должна быть смещена назад
    If (currentCharIndex < selectionStart) Then
     selectionStart = selectionStart - 1
    End If
    'He увеличивать значение счетчика символов, ибо мы должны
    'просмотреть символ, занявший место того символа,
    'который мы удалили
   Else
    'Символ является цифрой, все нормально.
    currentCharIndex = currentCharIndex + 1
   End If
  End If
 End While
 'Если превышена длина строки, усечь ее
 If (m_sb.Length > SSNumberLength) Then
  m_sb.Length = SSNumberLength
 End If
 'Возвратить новую строку
 Return m_sb.ToString()
End Function
Private m_in_OnChangeFunction As Boolean
Protected Overrides Sub OnTextChanged(ByVal e As EventArgs)
 '------------------------------------------------------------------
 'Если мы изменим свойство .Text, то будет осуществлен повторный
 'вход в обработчик. В этом случае мы не хотим предпринимать никаких
 'действий и должны просто выйти из функции без передачи события
 'куда-то еще.
 '------------------------------------------------------------------
 If (m_in_OnChangeFunction = True) Then
  Return
 End If
 'Заметьте, что сейчас мы находимся в функции OnChanged,
 'поэтому мы можем обнаружить повторное вхождение (см. код выше)
 m_in_OnChangeFunction = True
 'Получить текущее свойство .Text
 Dim oldText As String = Me.Text
 'Получить текущий индекс SelectionStart
 Dim selectionStart As Integer = Me.SelectionStart
 'Форматировать строку, чтобы она удовлетворяла нашим потребностям
 Dim newText As String = formatText_NNN_NN_NNNN(oldText, _
  selectionStart)
 'Если текст отличается от исходного, обновить
 'свойство .Text
 If (oldText <> newText) Then
  'Это приведет к повторному вхождению
  Me.Text = newText
  'Обновить местоположение точки вставки
  Me.SelectionStart = selectionStart
 End If
 'Мы принудительно обеспечили соответствие введенного текста правильному
 'формату, поэтому, если длина строки согласуется с длиной номера
 'карточки социального страхования, то мы знаем что он имеет
 'формат ###-##-####.
 If (Me.Text.Length = SSNumberLength) Then
  'Да, мы имеем полный номер карточки социального страхования
  m_inputIsFullValidEntry = True
 Else
  'Нет, мы пока не получили полный номер карточки социального страхования
  m_inputIsFullValidEntry = False
 End If
 'Вызвать наш базовый класс и сообщить всем объектам, которых это может
 'интересовать, что текст изменился
 MyBase.OnTextChanged(e)
 'Заметьте, что сейчас мы покидаем наш код и хотим отключить
 'проверку повторных вхождений в него.
 m_in_OnChangeFunction = False
End Sub
Protected Overrides Sub OnKeyPress( _
 ByVal e As System.Windows.Forms.KeyPressEventArgs)
 'Поскольку нам известно, что никакие буквы при вводе нам не нужны,
 'то просто игнорировать их, если они встречаются.
 Dim keyPressed As Char = e.KeyChar
 If (System.Char.IsLetter(keyPressed)) Then
  'Сообщить системе о том, что событие обработано
  e.Handled = True
  Return
 End If
 'Обработать нажатие клавиши обычным способом
 MyBase.OnKeyPress(e)
 End Sub
End Class

Оглавление книги


Генерация: 1.682. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз