Опубликован: 08.07.2011 | Доступ: свободный | Студентов: 1772 / 93 | Оценка: 4.15 / 4.08 | Длительность: 15:28:00
Лекция 5:

Взаимодействие приложения с базой данных

Проверка ввода данных

При вводе и редактировании данных важной задачей эффективного интерфейса является валидация – проверка вводимых данных. Если с данными можно связать определенные бизнес-правила (например, соответствие допустимому диапазону, корректность преобразования при вводе, определенный шаблон), то целесообразно проводить валидацию данных при их вводе. Элемент управления DataGrid позволяет выполнять проверку на уровне ячеек и на уровне строк. В строке DataGrid хранится определенный объект. В сетке DataGridEmployee отображаются объекты Employee. Каждая колонка сетки связана с определенным свойством класс Employee. Когда пользователь обновляет какое-либо свойство объекта Employee, в ходе проверки на уровне ячеек проверяются отдельные свойства объекта, привязанного к данным. Когда пользователь вносит изменения в строку, то есть в объект Employee, в ходе проверки на уровне строк проверяются целые объекты данных. Для улучшения качества интерфейса можно реализовать визуальную реакцию на ошибки проверки или использовать стандартные сигналы, предоставляемые элементом управления DataGrid.

Поставим задачу проверки шаблона при вводе свойства Email, то есть адреса электронной почты. В строке ввода должны присутствовать символы @ и точка.

Спроектируем правило проверки для привязки, которое будет использоваться со столбцом "Электронная почта". Для этого необходимо создать класс правила проверки EmailRule, который должен наследоваться от базового класса ValidationRule. Класс EmailRule поместим во вновь созданную папку ValidationRules проекта.

public class EmailRule: ValidationRule
{
    public override ValidationResult Validate(object value,
                    System.Globalization.CultureInfo cultureInfo)
    {
        string email = string.Empty;
        if (value != null)
        {
            email = value.ToString();
        }
        else
            return new ValidationResult(false, " Адрес электронной почты не задан! ");
        if (email.Contains("@") && email.Contains("."))
        {
            return new ValidationResult(true, null);
        }
        else
        {
            return new ValidationResult(false, 
					"Адрес электронной почты должен содержать 
					символы @ и (.) точки \n Шаблон адреса:			
					adres@mymail.com");
        }
    }
}

В классе правил проверки необходимо переопределить метод Validate, который возвращает результат проверки – экземпляр класса ValidationResult. Если проверка проходит успешно, тогда возвращаемым значением является объект класса ValidationResult, который создается с параметрами true и null.

return new ValidationResult(true, null);

Если проверка приводит к выявлению несоответствия, то класс ValidationResult, создается с параметрами false и строка сообщения об ошибке.

return new ValidationResult(false, "Адрес электронной почты должен 
содержать символы @ и (.) точки \n Шаблон адреса:   
adres@mymail.com");

Для использования объекта EmailRule в XAML-документе страницы PageEmployee добавим в её описание пространство имен WpfApplProject.ValidationRules.

xmlns:rule="clr-namespace:WpfApplProject.ValidationRules"

Внесем изменения в XAML-описание колонки Электронная почта.

<DataGridTextColumn  Header="Электронная почта" EditingElementStyle="{StaticResource errorStyle}">
    <DataGridTextColumn.Binding >
        <Binding Path="Email" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"
ValidatesOnExceptions ="True" >
            <Binding.ValidationRules>
                 <rule:EmailRule />
          </Binding.ValidationRules>
        </Binding>
    </DataGridTextColumn.Binding>
</DataGridTextColumn>

Для привязки Binding свойству ValidatesOnExceptions зададим значение true. Задание данного свойства обеспечивает использование элемента ExceptionValidationRule. ExceptionValidationRule предоставляет встроенное правило проверки, проверяющее возникновение исключений при обновлении свойства источника. В случае возникновения ошибки механизм привязки создает ValidationError с исключением и добавляет его в коллекцию Validation.Errors привязанного элемента. Отсутствие ошибок сбрасывает это состояние обратной связи проверки, если другое правило не вызовет событие проверки.

Правило проверки задается для свойства ValidationRules класса Binding.

<Binding.ValidationRules>
   <rule:EmailRule />
</Binding.ValidationRules>

Модель привязки данных WPF позволяет связывать ValidationRules с объектом Binding, используя пользовательские правила. Подсистема привязки проверяет каждое из ValidationRule, связанных с привязкой, каждый раз, когда вводимое значение (значение свойства цель привязки) переносится в свойство источник привязки.

В WPF имеются стандартные стили для отображения ячеек сетки при возникновении ошибки ввода, но они являются недостаточно информативными. Для более эффектного выделения ячейки сетки при ошибке ввода создадим специальный стиль errorStyle.

<Style x:Key="errorStyle" TargetType="{x:Type TextBox}">
    <Setter Property="Padding" Value="-2"/>
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="True">
            <Setter Property="Background" Value="Red"/>
            <Setter Property="BorderThickness" Value="1" />
            <Setter Property="ToolTip"
                    Value="{Binding RelativeSource={RelativeSource Self},
                Path=(Validation.Errors)[0].ErrorContent}"/>
        </Trigger>
    </Style.Triggers>
</Style>

В стиле errorStyle триггер срабатывает, когда свойство Validation.HasError принимает значение true. При этом цвет заливки ячейки становится красным и при наведении на ячейку указателя мыши выводится сообщение-подсказка (свойство ToolTip ), текст которого определяется в правиле проверки EmailRule при обнаружении ошибки (Validation.Errors)[0].ErrorContent).

Стандартные средства WPF при обнаружении ошибки ввода в ячейке помечают строку сетки красным восклицательным знаком. Создадим шаблон ControlTemplate для визуального указания ошибки при проверке строки. Данный шаблон задается для свойства RowValidationErrorTemplate сетки DataGrid. Проектируемый шаблон должен обеспечить вывод красного круга с белым восклицательным знаком слева от строки сетки с обнаруженной ошибкой ввода. При наведении указателя мыши на круг должна выводиться подсказка, сформированная в классе правил проверки ввода.

<DataGrid.RowValidationErrorTemplate>
    <ControlTemplate>
        <Grid Margin="0,-2,0,-2"
              ToolTip="{Binding RelativeSource={RelativeSource FindAncestor,
                                           AncestorType={x:Type DataGridRow}},
            Path=(Validation.Errors)[0].ErrorContent}">
            <Ellipse StrokeThickness="0" Fill="Red" Width="{TemplateBinding FontSize}"
                                                 Height="{TemplateBinding FontSize}" />
            <TextBlock Text="!" FontSize="{TemplateBinding FontSize}" FontWeight="Bold"
                                    Foreground="White" HorizontalAlignment="Center"  />
        </Grid>
    </ControlTemplate>
</DataGrid.RowValidationErrorTemplate>

На рис. 5.14 и рис. 5.15 приведены результаты тестирования страницы PageEmployee при наличии ошибки ввода адреса электронной почты.

Визуализация ошибки ввода при наведении указателя мыши на ячейки сетки

увеличить изображение
Рис. 5.14. Визуализация ошибки ввода при наведении указателя мыши на ячейки сетки
Визуализация ошибки ввода при наведении указателя мыши на предупреждение для строки

увеличить изображение
Рис. 5.15. Визуализация ошибки ввода при наведении указателя мыши на предупреждение для строки
Александр Петров
Александр Петров

При загрузке данных из БД возникает исключение InvalidOperationException с сообщением: Элемент коллекции должен быть пустым перед использованием ItemsSource. Знаю, что для заполнения DataGrid можно использовать коллекции Items или ItemsSource, но одновременно их использовать нельзя: если задано значение для свойства ItemsSource и в коде C# добавляется элемент в Items, возникает исключение. 
Вопрос, как отследить и отключить добавление элемента в Items?

Максим Спиридонов
Максим Спиридонов

В пятой лекции на второй странице в компиляторе выскакивает ошибка в строчке :

ObjectQuery<Employee> employees = DataEntitiesEmployee.Employees;

Ошибка CS0029

Не удается неявно преобразовать тип "System.Data.Entity.DbSet<WpfApplProject.Employee>" в "System.Data.Entity.Core.Objects.ObjectQuery<WpfApplProject.Employee>".

в using прописал все как положено, здесь похоже именно с преобразованием типов проблемы