среда, 4 февраля 2015 г.

Дано:
 - Два поля ввода исходных данных.
 - Кнопка, для осуществления по ним расчета.
 - Три поля вывода результата.

Требуется:
 - Реализовать проверки введенных данных перед расчетами.

Пусть данные на форме перед расчетами проверяются методом ValidateData(). 
У меня есть два быстро приходящих в голову способа реализовать этот метод:

void ValidateData
{
     try
     {
         Convert.ToInt32(this.GirlsCountTB.Text);
     } catch { ... }
     ....
}
Но вообще, try - catch это долго и неэффективно - раз.
Мне в любом случае придется делать эту конвертацию впоследствии, при переходе к расчетам - два. Поэтому второй вариант:
void ValidateData
{
    int girls = 0;
    if (!Int32.TryParse(this.GirlsCountTB.Text, out girls)) { ... }
}

Это уже по-человечески, но куда мне деть результат? Можно вернуть, но у меня здесь два поля, которые надо проверить. А если их будет 10? Можно создать и заполнить словарь. И на этом я бы и остановилась и тогда поста бы не было. Но... Тем временем, коллега на обеде рекомендует мне третий вариант. 
"А как же дзен обработки ввода? Используй событие TextChanged." Идея кажется мне неплохой... 

      -  И... в момент события TextChanged отображение изменения уже произошло. Отменять действие уже поздно.
      -  В списке есть TextInput, но интернет мне услужливо сообщает, что это событие блокируется элементом TextBox. 
      -  Зато есть PreviewTextInput. Оно не блокируется, позволяет отменить ввод...  в общем все прекрасно. Но есть нюанс: это событие не генерируется при нажатии пробела. Пробел нам предлагают обрабатывать дополнительно через KeyDown. 
И в итоге тогда обработка данных происходит в трех местах:

  1. PreviewTextInput
  2. KeyDown
  3. ValidateData (потому что если ни одно из событий не произошло поле остается пустым... и не валидным. И нам надо об этом знать).
В общем идея с событиями мне кажется несостоятельной. Странно?..
Не очень, WPF подразумевает активное, судя по всему даже повсеместное, использование привязок. В этом случае ввод проверяется на уровне объекта, вместе с бизнес-логикой. И все эти события ввода с клавиатуры нам не нужны. 
Но пока у меня в архитектуре нет сформированных объектов, хотя, подозреваю, они еще будут, но пока это будет выглядеть так:

private bool ValidateData()
{
    List<string> errors = new List<string>();
    int girls = 0;
    double timeForOne = 1.0;

    if (this.GirlsCountTB.Text == "")
       errors.Add("Не задан размер массовки.");
                        
    if (!Int32.TryParse(this.GirlsCountTB.Text, out girls))
       errors.Add("Некорректное число массовщиц.");

    if (this.OneVarTimeTB.Text == "")
       errors.Add("Не задано время на проработку одного варианта.");

    if (!Double.TryParse(this.OneVarTimeTB.Text, out timeForOne))
       errors.Add("Некорректное время обработки одного варианта");

    ShowErrorMsg(errors);

    return (errors.Count == 0);

}

Использованные материалы по теме:

http://samorazvitie.net/book/80-osnovy-proektir-interfejsov-s-ispolzovaniem-texnologii-windows-presentation-foundation-shamshev-a/36-55-sobytiya-wpf.html

Комментариев нет:

Отправить комментарий