Опубликован: 08.07.2011 | Уровень: для всех | Доступ: платный
Лекция 5:

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

Привязка элементов управления к источнику данных

Для взаимодействия приложения с базой данных необходимо в коде класса PageEmployee объявить статическое свойство контекста данных DataEntitiesEmployee сформированной EDM-модели. На данном этапе проектирования приложения это свойство можно объявлять только общедоступным, то есть publi c, но в дальнейшем нам потребуется использовать это свойство в других классах без создания экземпляра класса PageEmployee, что возможно только в случае, если это свойство будет статическим.

public static TitlePresonalEntities DataEntitiesEmployee { get; set; }

Также необходимо объявить коллекцию ListEmployee для работы приложения с коллекцией объектов Employee.

public PageEmployee()
{
    DataEntitiesEmployee = new TitlePresonalEntities();
    InitializeComponent();
    ListEmployee = new ObservableCollection<Employee>();
}

Формирование данных для приложения, которые должны предоставляться из базы данных, будем создавать при загрузке страницы PageEmployee. Для этого в XAML-документ Page добавим свойство Loaded.

Loaded="Page_Loaded"

В код класса PageEmployee включаем обработчик Page_Loaded.

private void Page_Loaded(object sender, RoutedEventArgs e)
{
    ObjectQuery<Employee> employees = DataEntitiesEmployee.Employees;
    var queryEmployee = from employee in employees
                        orderby employee.Surname
                        select employee;
     foreach (Employee emp in queryEmployee)
    {
        ListEmployee.Add(emp);
    }
    DataGridEmployee.ItemsSource = ListEmployee;
}

Поле employees имеет тип ObjectQuery<Employee>. Класс ObjectQuery<Т> представляет запрос, возвращающий коллекцию типизированных сущностей с любым количеством элементов. Запрос сформируем с помощью технологии LINQ [ 1 ] , [ 6 ] , [ 9 ] .

var queryEmployee = from employee in employees
            orderby employee.Surname
            select employee;

Результаты запроса отсортируем по фамилии сотрудника ( orderby employee.Surname ). Далее формируем коллекцию ListEmployee сотрудников и источник данных для сетки DataGridEmployee.

foreach (Employee emp in queryEmployee)
    {
        ListEmployee.Add(emp);
    }
DataGridEmployee.ItemsSource = ListEmployee;

В результате проектирования в приложении сформирована коллекция с данными из таблицы Employee базы данных TitleEmployee. Следующей задачей является настройка сетки DataGridEmployee для корректного отображения данных.

Вначале модифицируем общее описание DataGrid.

<DataGrid Name="DataGridEmployee"  
ItemsSource="{Binding}"
AutoGenerateColumns="False" 
HorizontalAlignment="Left" 
MaxWidth="1000" MaxHeight="295" 
RowBackground="#FFE6D3EF" 
AlternatingRowBackground="#FC96CFD4" 
BorderBrush="#FF1F33EB" 
BorderThickness="3"  
IsReadOnly="True" 
RowHeight="25" 
Cursor="Hand"
CanUserAddRows="False" 
CanUserDeleteRows="False">

Определим привязку для источника данных.

ItemsSource="{Binding}"

Отменим автоматическую генерацию столбцов.

AutoGenerateColumns="False"

Установим привязку к левому краю страницы.

HorizontalAlignment="Left"

Определим максимальные размеры сетки.

MaxWidth="1000" MaxHeight="295"

Установим основной и альтернативный цвета заливки сетки.

RowBackground="#FFE6D3EF" 
AlternatingRowBackground="#FC96CFD4"

Определим цвет заливки и толщину линии для рамки сетки.

BorderBrush="#FF1F33EB" 
BorderThickness="3"

Определим высоту строк сетки.

RowHeight="25"

Переопределим форму курсора при наведении указателя мыши на таблицу DataGridEmployee.

Cursor="Hand"

Привязка текстового поля

Для каждого текстового столбца зададим свойство привязки Binding. В расширении разметки привязки данного свойства определим свойство класса Employee, к которому привязывается колонка. Для колонки Фамилия это свойство Surname. Далее указываем режим двусторонней привязки ( Mode=TwoWay ), который определяет синхронное обновление как источника, так и приемника привязки. Способ обновления источника привязки задается свойством UpdateSourceTrigger, которое принимает значение PropertyChanged, что соответствует немедленному обновлению источника привязки каждый раз при изменении свойства цели привязки.

<DataGridTextColumn Header="Фамилия" 
	Binding="{Binding Surname, Mode=TwoWay, 
	UpdateSourceTrigger=PropertyChanged}"/>

После запуска приложения страница PageEmployee имеет вид, приведенный на рис. 5.7.

Страница PageEmployee с привязанными в таблице текстовыми полями

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

При загрузке данных из БД возникает исключение 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 прописал все как положено, здесь похоже именно с преобразованием типов проблемы

Igor Chelyadinski
Igor Chelyadinski
Беларусь, Минск, №54, 2013
Валентина Алешина
Валентина Алешина
Россия