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