Главная » Silverlight » Проверка данных

0

Когда система связывания Silverlight получает некорректные данные, она обычно игнорирует их. Ниже приведены три типа ошибок, происходящих при редактировании поля, связанного в двустороннем режиме.

•       Неправильный тип данных. Например, числовое поле, такое как UnitCost (Цена продукта), не может содержать буквы или специальные символы. Кроме того, оно не может содержать слишком большие числа (больше чем 1.7976931348 6231570Е+308).

•       Исключение, сгенерированное процедурой установки свойства. Например, в процедуру установки (setter) свойства UnitCost можно включить код проверки диапазона, генерирующий исключение при попытке ввести отрицательное число.

•    Свойство в режиме "только чтение". Такое свойство не может получать данные.

Когда происходит одна из этих ошибок, пользователь может не заметить ее. Это объ­ясняется тем, что система связывания Silverlight не предоставляет визуального контро­ля. Некорректные значения остаются в связанном элементе управления, но не приме­няются в связанном объекте.

Чтобы избежать ошибок, рекомендуется извещать о них пользователя как можно быстрее. Легче всего применить два свойства связывания — ValidatesOnException и NotifyOnValidationError — вынуждающих Silverlight генерировать события извеще­ния об ошибках.

Свойство ValidatesOnException

Установка свойства ValidatesOnException — первый обязательный этап реализации проверки любого типа. Если присвоить этому свойству значение true, система связы­вания данных реагирует на любые ошибки как в преобразователе типов, так и в проце­дуре установки свойства. Когда же оно равно false (значение по умолчанию), система связывания завершается, ничего не сообщив. Объект данных не обновляется, однако неправильное значение остается в элементе управления.

Ниже приведен пример использования свойства ValidatesOnException в свойстве UnitCost.

cTextBox Margin="5" Grid.Row="2" Grid.Column="l" x:Name="txtUnitCost" Text="(Binding UnitCost, Mode=TwoWay, ValidatesOnExceptions=True}"></TextBox>

Приведенная выше разметка позволяет приложению обнаруживать и отображать ошибки. Естественно, должно быть определено двустороннее связывание данных с эле­ментом управления, поддерживающим группу состояний ValidationState. Ниже пере­числены элементы, поддерживающие эту группу.

•     TextBox

•     PasswordBox

•     CheckBox

•     RadioButton

•     ListBox

•     ComboBox

В главе 13 вы узнали о состояниях элементов управления — именованных анимаци­ях, применяемых в заданное время. Для реализации средств проверки элемент управ­ления должен поддерживать три состояния: Valid, InvalidUnfocused и InvalidFocused. Вместе они составляют группу ValidationState и позволяют элементу управления из­менять свой внешний вид, когда он содержит неправильные данные.

Рассмотрим в качестве примера текстовое поле с неправильными данными. В клас­се Product приведенный ниже код используется для обнаружения отрицательных цен и генерации объектов исключений.

private double unitCost;

public double UnitCost

{

get { return unitCost; }

set

{

if (value < 0) throw new ArgumentException ( "He может быть меньше 0.");

unitCost = value;

}

}

Что произойдет, если пользователь введет отрицательное число? Процедура уста­новки свойства сгенерирует исключение ArgumentException. Поскольку свойство ValidatesOnException равно true, исключение будет перехвачено системой связывания данных, которая переключит группу ValidationState текстового поля с состояния Valid в состояние InvalidFocused (если текстовое поле имеет фокус) или InvalidUnfocused (если не имеет).

Совет. Если вы запускаете приложение в Visual Studio, установите прерывание для всех исключений. Тогда Visual Studio сообщит об исключении ArgumentException и переключится в режим прерывания. Сначала вы не увидите облака сообщений. Чтобы увидеть, что произойдет, когда исключение достигнет системы связывания данных, выберите команду Debug^Continue (Отладка^Продолжить) или нажмите клавишу <F5>.

Когда текстовое поле имеет фокус, по его периметру выводится красная рамка с пик­тограммой ошибки (небольшой красный треугольник, расположенный в правом верх­нем углу рамки). При наведении указателя на пиктограмму ошибки справа появляется текст сообщения в красном всплывающем облаке. На рис. 16.2 показаны оба состояния.

Рис. 16.2. Состояния InvalidUnfocused (слева) и InvalidFocused (справа) текстового поля

Примечание. Чтобы красное облако сообщений было правильно выведено, для него должно быть достаточно места между текстовым полем и краем окна браузера. Если место есть справа, облако будет выведено справа, если нет — то слева. Облако закрывает элементы страницы, которые "попадут ему под руку". Однако оно не может выходить за пределы окна браузера. На рис. 16.2 ширина текстового поля UnitPrice ограничена, чтобы оставалось свободное место справа. Если приведенное в облаке сообщение не помещается в доступном пространстве, его часть отсекается.

На первый взгляд, облако сообщения об ошибке очень полезно и его легко приме­нить. Элемент управления сам позаботится о визуальных параметрах, нужно лишь за­дать текст сообщения. Однако при внедрении системы проверки в шаблон элемента управления проявляется ее существенный недостаток: чтобы изменить способ вывода сообщения об ошибке (или отключить вывод), нужно заменить весь шаблон и добавить в новый шаблон все несвязанные состояния и элементы разметки. Обычно шаблон эле­мента управления довольно длинный, поэтому данный процесс весьма утомительный, чреват ошибками и подвержен существенным ограничениям. Например, необходимость замены шаблона может заставить отказаться от использования шаблона, предостав­ляющего более привлекательный интерфейс, но созданного другим разработчиком.

Примечание. В главе 17 вы узнаете о еще одном способе вывода информации об ошибке, основанном на использовании элемента ValidationSummary. Он извлекает сообщения об ошибках из коллекции дочерних элементов и размещает их в одном месте.

Свойство NotifyOnValidationError

После присвоения свойству ValidatesOnException значения true можно присвоить его и свойству MotifyOnValidationError. Тогда Система связывания данных при воз­никновении ошибки будет генерировать событие BindingValidationError.

CTextBox Margin="5" Grid.Row="2" Grid.Column="l" x:Name="txtUnitCost" Text="{Binding UnitCost, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=True}" > </TextBox>

Событие BindingValidationError поднимается вверх по иерархии элементов. Следовательно, его можно обработать не только в элементе, в котором произошла ошиб­ка (например, в элементе TextBox), но и в любом родительском элементе. Коды обра­ботки ошибок можно создать отдельно для каждого поля, однако обработка на более высоком уровне позволяет применить один и тот же код для многих элементов.

<Grid Name="gridProductDetails"

BindingValidationError="Grid_BindingValidationError">

В обработчик нужно ввести код, выполняющий необходимые операции при возник­новении ошибки. Обычно код выводит какой-либо индикатор ошибки, например сооб­щение рядом с элементом. В некоторых случаях код может восстановить текущее значе­ние. Ниже приведен код, который выводит сообщение об ошибке и отображает текущее значение (рис. 16.3). Кроме того, код возвращает фокус текстовому полю, в котором воз­никла ошибка. Элемент управления остается в состоянии invalidFocused, не переходя в состояние invalidUnfocused, поэтому облако сообщения об ошибке остается видимым.

private void Grid_BindingValidationError (object sender, ValidationErrorEventArgs e)

{

// Вывод сообщения

lbllnfo.Text = e.Error.Exception.Message; lbllnfo.Text += "\nB элементе все еще хранится значение’Ч ((Product)gridProductDetails.DataContext).

UnitCost.ToString();

// Возвращение фокуса txtUnitCost.Focus ();

}

Событие BindingValidationError генерируется, только если измененное значе­ние зафиксировано. Если элементом является текстовое поле, фиксация выполняется в момент потери фокуса. Чтобы перехватить ошибку раньше, можно применить метод BindingExpression. UpdateSource (), который задает немедленное обновление текстово­го поля во время ввода данных пользователем.

Совет. Если не переустановить содержимое текстового поля, неправильное значение останется на экране, даже когда его уже нет в связанном объекте данных. Такое поведение иногда желательно, потому что оно предоставляет пользователю возможность исправить значение.

Все операции, закодированные в обработчике события, происходят дополнительно к изменениям состояния элемента управления. К сожалению, выборочно отключить сооб­щения об ошибках, генерируемые элементом управления, невозможно, хоть это и было бы полезно при обработке ошибки BindingValidationError.

Рис. 16.3. Пример обработки ошибки

Класс Validation

Важно отметить, что для обнаружения неправильных данных не обязательно реаги­ровать на событие BindingValidationError. Проверить связанный элемент управления можно в любой момент времени с помощью статического метода GetHasError () класса Validation. Он возвращает значение true, если элемент управления не прошел про­верку. Полезен также метод Validation.GetErrors (), который возвращает коллекцию объектов исключений.

Эти два метода помогают сделать проверку более гибкой. Например, можно вызвать метод HasError () и запретить пользователю переходить к следующему этапу. Можно вы­полнить определенную процедуру, если существуют неправильные данные. И наконец, ме­тод GetErrors () можно применить для вывода полного, окончательного, списка ошибок.

Источник: Мак-Дональд, Мэтью. Silverlight 3 с примерами на С# для профессионалов. : Пер. с англ. —- М. : ООО «И.Д. Вильяме», 2010. — 656 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии