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

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

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

using System;
//----------------------------------------------------------------------
//Этот класс является элементом управления, производным от TextBox.
//Он наследует все графические свойства TextBox, но добавляет фильтрацию
//содержимого текстового окна, тем самым гарантируя,
//что вводимый текст будет соответствовать следующему формату:
//###-##-####.
//Этот формат соответствует формату номеров карточек социального
//страхования, которые используются в США.
//----------------------------------------------------------------------
public class  SocialSecurityTextBox: System.Windows.Forms.TextBox {

 private bool  m_inputIsFullValidEntry;
 //------------------------------------
 //Указывает, получен ли номер карточки
 //социального страхования полностью
 //------------------------------------
 public bool  IsFullValidInput {
  get {return m_inputIsFullValidEntry;}
 }
 //Объект StringBuilder, который мы будем часто использовать
 System.Text.StringBuilder m_sb;
 //Максимальная длина обрабатываемых строк
 const int  SSNumberLength = 11;

 //-----------

 //Конструктор
 //-----------
 public  SocialSecurityTextBox() {

  //Распределить память для нашего объекта StringBuilder и предоставить
  //место для нескольких дополнительных рабочих символов по умолчанию
  m_sb = new System.Text.StringBuilder(SSNumberLength + 5);
  m_inputIsFullValidEntry = false;
 }
 //---------------------------------------------------------------------
 //Форматировать поступающий текст с целью установления его соответствия
 //нужному формату:
 //
 // Формат номера карточки социального страхования : ###-##-####
 // символы: 01234567890
 //
 // [in] inString : Текст, который мы хотим форматировать
 // [in/out] selectionStart: Текущая точка вставки в тексте;
 // она будет смещаться в связи с удалением
 // и добавлением нами символов
 //----------------------------------------------------------------------
 private string formatText_NNN_NN_NNNN(string inString, ref int selectionStart) {
  const int  firstDashIndex = 3;

  const int secondDashIndex = 6;

  //Удалить старые данные и поместить входную строку
  //в объект StringBuilder, чтобы мы могли с ней работать.
  m_sb.Length = 0;
  m_sb.Append(inString);
  //------------------------------------------------------------
  //Просмотреть каждыйсимвол в строке, пока не будет
  //достигнута максимальная длина нашего форматированного текста
  //------------------------------------------------------------
  int  currentCharIndex;
  currentCharIndex = 0;
  while ((currentCharIndex < m_sb.Length) && (currentCharIndex < SSNumberLength)) {
   char  currentChar;
   currentChar = m_sb[currentCharIndex];
   if ((currentCharIndex == firstDashIndex) || (currentCharIndex == secondDashIndex))
   //-------------------------------
   //Данным символом должен быть "-"
   //-------------------------------
   {
    if (currentChar != '-') {
     //Вставить дефис
     m_sb.Insert(currentCharIndex, "-");
     //Если мы добавили символ перед точкой вставки,
     //она должна быть смещена вперед
     if (currentCharIndex <= selectionStart) {
      selectionStart++;
     }
    }
    //Этот символ годится, перейти к следующему символу
    currentCharIndex++;
   } else
   //-------------------------
   //Символ должен быть цифрой
   //-------------------------
   {
    if (System.Char.IsDigit(currentChar) == false) {
     //Удалить символ
     m_sb.Remove(currentCharIndex, 1);
     //Если мы добавили символ перед точкой вставки,
     //она должна быть смещена назад
     if (currentCharIndex < selectionStart) {
      selectionStart--;
     }
     //He увеличивать значение счетчика символов, ибо мы должны
     //просмотреть символ, занявший место того символа,
     //который мы удалили
    } else {
     //Символ является цифрой, все нормально.
     currentCharIndex++;
    }
   }
  }
  //Если превышена длина строки, усечь ее
  if (m_sb.Length > SSNumberLength) {
   m_sb.Length = SSNumberLength;
  }
  //Возвратить новую строку
  return m_sb.ToString();
 }
 bool m_in_OnChangeFunction;
 protected override void OnTextChanged(EventArgs e) {

  //------------------------------------------------------------------
  //Если мы изменим свойство .Text, то будет осуществлен повторный
  //вход в обработчик. В этом случае мы не хотим предпринимать никаких
  //действий и должны просто выйти из функции без передачи события
  //куда-то еще.
  //------------------------------------------------------------------
  if (m_in_OnChangeFunction == true) {
   return;
  }
  //Заметьте, что сейчас мы находимся в функции OnChanged,
  //поэтому мы можем обнаружить повторное вхождение (см. код выше)
  m_in_OnChangeFunction = true;
  //Получить текущее свойство .Text
  string oldText = this.Text;
  //Получить текущий индекс
  SelectionStart int selectionStart = this.SelectionStart;
  //Форматировать строку, чтобы она удовлетворяла нашим потребностям
  string newText = formatText_NNN_NN_NNNN(oldText, ref selectionStart);
  //Если текст отличается от исходного, обновить
  //свойство .Text
  if (System.String.Compare(oldText, newText) != 0) {
   //Это приведет к повторному вхождению
   this.Text = newText;
   //Обновить местоположение точки вставки
   this.SelectionStart = selectionStart;
  }
  //Мы принудительно обеспечили соответствие введенного текста
  //правильному формату, поэтому, если длина строки согласуется с длиной
  //номера карточки социального страхования, то мы знаем что она имеет
  //формат ###-##-####.
  if (this.Text.Length == SSNumberLength) {
   //Да, мы имеем полный номер карточки социального страхования
   m_inputIsFullValidEntry = true;
  } else {
   //Нет, мы пока не получили полный номер карточки социального страхования
   m_inputIsFullValidEntry = false;
  }
  //Вызвать наш базовый класс и сообщить всем объектам, которых это
  //может интересовать, что текст изменился
  base.OnTextChanged(e);
  //Заметьте, что сейчас мы покидаем наш код и хотим отключить
  //проверку повторных вхождений в него.
  m_in_OnChangeFunction = false;
 }
 protected override void OnKeyPress(System.Windows.Forms.KeyPressEventArgs e) {
  //Поскольку нам известно, что никакие буквы при вводе нам не нужны,
  //то просто игнорировать их, если они встречаются.
  char keyPressed = e.KeyChar;
  if (System.Char.IsLetter(keyPressed)) {
   //Сообщить системе о том, что событие обработано
   e.Handled =true;
   return;
  }
  //Обработать нажатие клавиши обычным способом
  base.OnKeyPress(e);
 } //Конец функции
} //Конец класса

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


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