Преобразование и проверка данных
При выполнении привязки данных достаточно часто тип или представление объекта-источника и целевого объекта не совпадают, и встает задача преобразования данных. Преобразование данных может проводится неявно, когда целевой тип может представлять любое допустимое значение типа источника, но это не всегда может удовлетворять пользователя.
В технологии WPF преобразование данных используется для:
· форматирования данных к строковому представлению;
· создания специфических типов WPF;
· условного изменения свойств элемента на основе привязанных данных.
Для проектирования преобразователя значений необходимо выполнить следующее:
1. Создать класс, реализующий интерфейс IValueConverter.
2. Добавить атрибут ValueConversion в объявление класса и специфицировать исходный и отображаемый формат.
3. Реализовать метод Convert(), преобразующий данные из исходного формата в отображаемый формат.
4. Реализовать метод ConvertBack(), выполняющий обратное преобразование значения данные из отображаемого форма в исходный формат.
В случае преобразования вещественного значения в строковое можно использовать метод ToString(), а для обратного преобразования - Single.Parse().
Спроектируем класс конвертора StringToFloatConvert для преобразования строковых данных в вещественное число.
[ValueConversion(typeof(float),typeof(string))]public class StringToFloatConvert : IValueConverter{ public object Convert(object value, Type typeTarget, object param, CultureInfo culture) { if (value != null) return value.ToString(); else return string.Empty; } public object ConvertBack(object value, Type typeTarget, object param, CultureInfo culture) { if ((value != null) && (value.ToString() != "")) return Single.Parse(value.ToString(), NumberStyles.Float); else return 0; }}Обратите внимание на то, что для преобразования строки данных в вещественное число используется метод Single.Parse(value.ToString(), NumberStyles.Float). Данный метод преобразует строковое представление числа в указанном стиле в эквивалентное ему число одиночной точности с плавающей запятой, то есть для ввода используется не точка, а запятая.
Для подключения преобразователя необходимо к дескриптору окна добавить атрибут с отображением пространства имен проекта на префикс пространства имен XML:
xmlns:s="clr-namespace:Wpf_Primer1"Далее необходимо создать экземпляр класса StringToFloatConvert и присвоить его свойству Convert в привязке элемента TextBox:
<TextBox Grid.Column="1" Margin="5,5,28,15" Name="textBox1"> <TextBox.Text> <Binding Path="Factor" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"> <Binding.Converter> <s:StringToFloatConvert /> </Binding.Converter> </Binding> </TextBox.Text></TextBox>Тестирование приложения показывает, что при вводе цифровой строки с запятой, то есть вещественного числа с плавающей запятой, например "0,3", выводится также строка "0,3" ( рис. 3.8). При вводе цифровой строки с точкой формируется программное прерывание методом Single.Parse(value.ToString(), NumberStyles.Float).
Рис. 3.8.Проверка корректности привязки с преобразованием данных
Теперь вернемся к вопросу проверки достоверности вводимых данных. Логика проверки достоверности вводимых данных должна перехватывать некорректные значения и отвергать их.
Технология WPF предполагает два варианта проверки достоверности данных для перехвата неверных значений:
· инициирование ошибки в объекте данных путем генерации исключения при установке свойства;
· определение проверки достоверности на уровне привязки.
Спроектируем правило проверки достоверности ввода данных путем создания класса ValidationFactor, который должен быть наследником класса правил ValidationRule из пространства имен System.Windows.Control:
public class ValidationFactor: ValidationRule{ public float Min { get; set;} public float Max { get; set;} public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo) { try { if (((string)value).Length > 0) Window1.Factor.Factor = Single.Parse((string)value, NumberStyles.Float); if((string)value == "") Window1.Factor.Factor = 0; } catch (Exception e) { return new ValidationResult(false, " Веден недопустимый символ! "); } if ((Window1.Factor.Factor < Min) || (Window1.Factor.Factor > Max)) return new ValidationResult(false, " Вводимое значение вне диапазона от " + Min + " до " + Max + ". "); else return new ValidationResult(true, null); }}В классе ValidationFactor определены свойства Min и Max, описывающие минимальное и максимально возможное значения вводимого вещественного числа и переопределен метод Validate() для требуемой проверки достоверности. При проверке достоверности используют перегруженную версию метода Single.Parse(), принимающего значение из перечисления NumberStyles. Это связано с тем, что проверка достоверности всегда выполняется перед преобразованием данных. Если применяется средство проверки достоверности и преобразователь к одному полю, то нужно обеспечить успех проверки достоверности. Успех или неудача логики проверки достоверности определяется возвращаемым объектом ValidationResult. Свойство IsValid указывает на успех проверки достоверности, и если проверка не прошла, то свойство ErrorContent представляет объект, описывающий ошибку.
Создадим экземпляр класса ValidationFactor и присвоим его свойству ValidationRules в привязке элемента TextBox:
<TextBox Grid.Column="1" Margin="5,5,28,15" Name="textBox1"> <TextBox.Text> <Binding Path="Factor" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"> <Binding.Converter> <s:StringToFloatConvert /> </Binding.Converter> <Binding.ValidationRules> <s:ValidationFactor Min="0" Max="1"/> </Binding.ValidationRules> </Binding> </TextBox.Text></TextBox>Свойствам Min и Max класса ValidationFactor определим значения соответственно 0 и 1.
Тестирование приложения показывает, что при вводе корректного значения приложение работает правильно, а при вводе некорректного символа или числа вне интервала [0,1] происходит подсвет рамки элемента TextBox красным цветом ( рис. 3.9).
Рис. 3.9.Проверка корректности ввода символов
На рис. 3.9 показан ввод недопустимого нецифрового символа и недопустимого по значению числа.
Следует отметить, что коллекция Binding.ValidationRules может состоять из неограниченного числа правил. Когда значение фиксируется в источнике, WPF будет проверять каждое правило проверки достоверности по порядку. Если все проверки достоверности пройдут успешно, то WPF вызовет преобразователь данных и применит значения к источнику. Если проверка не пройдет, то текстовое поле будет очерчено красным цветом, будут установлены свойства HasError и Error и инициируется событие Error.
Для обработки события Error необходимо установить свойство Binding.NotifyOnValidationError в True:
<Binding Path="Factor" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">Событие Error является маршрутизируемым, использует передачу вверх и поэтому его можно обработать в родительском контейнере, например в Grid окна:
<Grid Name="gridPrimir" Height="85" Validation.Error="gridPrimir_Error">Код обработчика будет отображать сообщение с информацией об ошибке:
private void gridPrimir_Error(object sender, ValidationErrorEventArgs e){ if (e.Action == ValidationErrorEventAction.Added) { MessageBox.Show(e.Error.ErrorContent.ToString(), "Предупреждение", MessageBoxButton.OK, MessageBoxImage.Warning); }}Свойство ValidationErrorEventArgs.Error представляет объект ValidationError, который содержит информацию об исключении ( Exception ), сформированном в правиле ( ValidationRule ), ассоциированном с объектом Binding ( BindingInError ) и специальную информацию, возвращаемую объектом ValidationRule ( ErrorContent ). На рис. 3.10 и рис. 3.11 приведены реакция приложения на ввод некорректных данных.
Рис. 3.10.Реакция на ввод недопустимого символа
увеличить изображение
Рис. 3.11.Реакция на ввод недопустимого числа
Информацию об ошибке можно получить и другим способом. Можно отобразить сообщение об ошибке в ToolTip элемента TextBox. При этом сообщение об ошибке будет появляться, когда пользователь поместим курсор мыши над элементом TextBox. Для реализации такого варианта необходимо создать шаблон ошибок, который будет содержать триггер, реагирующий на присваивание свойству Validation.HasError значения true и применит ToolTip с сообщением об ошибке:
<Window.Resources> <Style TargetType="{x:Type TextBox}" > <Style.Triggers> <Trigger Property="Validation.HasError" Value="True"> <Setter Property="ToolTip" Value= "{Binding RelativeSource = {RelativeSource Self}, Path = (Validation.Errors)[0].ErrorContent}" /> </Trigger> </Style.Triggers> </Style></Window.Resources>При формировании свойства Path свойство Validation.Errors заключается в скобки, так как оно является присоединенным свойством, и используется индексатор для извлечения объекта ValidationError из коллекции для получения содержания ошибки ErrorContent. На рис. 3.12 и рис. 3.13 приведены примеры применения подсказки для проверки ввода данных.
Рис. 3.12.Подсказка при вводе недопустимого символа
Рис. 3.13.Подсказка при вводе недопустимого числа
Дата добавления: 2015-04-15; просмотров: 845;