При загрузке данных из БД возникает исключение InvalidOperationException с сообщением: Элемент коллекции должен быть пустым перед использованием ItemsSource. Знаю, что для заполнения DataGrid можно использовать коллекции Items или ItemsSource, но одновременно их использовать нельзя: если задано значение для свойства ItemsSource и в коде C# добавляется элемент в Items, возникает исключение. |
Разработка бизнес приложения Silverlight
Задание 4. Разработать методы манипулирования данными – 3 часа
Редактирование данных. На странице приложения создадим кнопки buttonNew, buttonEdit и buttonDelete для реализации выполнения соответствующих операций.
Добавьте в клиентскую часть приложения дочернее окно, с помощью которого будем редактировать и добавлять данные. Для этого в помощнике Добавление нового элемента необходимо выбрать шаблон Дочернее окно Silverlight (1 – рис. 11.21) и задать имя EmployeeChildWindow (2 – рис. 11.21).
В конструкторе окна EmployeeChildWindow откроем вкладку Источники данных и для сущности Employee сервиса данных EmployeeDomainContext зададим формат представления в виде Таблицы ( рис. 11.22). Для атрибутов сущности Employee задайте форматы в соответствии с форматами, представленными на рис. 11.23
С помощью мыши перетащите сущность Employee из вкладки Источники данных в конструктор окна EmployeeChildWindow. В результате будут сформированы элементы управления для работы со свойствами сущности Employee ( рис. 11.23).
В XAML-описание окна будет добавлен контекст данных для сущности Employee.
<riaControls:DomainDataSource AutoLoad="True" d:DesignData="{d:DesignInstance my1:Employee, CreateList=true}" Name="employeeDomainDataSource" Height="0" Width="0" LoadedData="employeeDomainDataSource_LoadedData" QueryName="GetEmployeesQuery"> <riaControls:DomainDataSource.DomainContext> <my:EmployeeDomainContext /> </riaControls:DomainDataSource.DomainContext> </riaControls:DomainDataSource>
Теперь следует создать вызов дочернего окна из страницы EmployeePage при нажатии кнопки buttonEdit.
private void buttonEdit_Click(object sender, RoutedEventArgs e) { Employee employeeEdit = employeeDataGrid.SelectedItem as Employee; if (employeeEdit != null) { EmployeeChildWindow winEmpEdit = new EmployeeChildWindow(employeeEdit); winEmpEdit.Closed += new EventHandler(winEmpEdit_Closed); winEmpEdit.Title = "Редактирование данных"; winEmpEdit.Show(); } }
В обработчике нажатия кнопки buttonEdit создается экземпляр employeeEdit сущности Employee на основе выделенной в текущий момент строки сетки данных employeeDataGrid.
Employee employeeEdit = employeeDataGrid.SelectedItem as Employee;
Если объект employeeEdit существует, то создается экземпляр winEmpEdit дочернего окна EmployeeChildWindow, которому в качестве параметра передается экземпляр сущности данных employeeEdit.
EmployeeChildWindow winEmpEdit = new EmployeeChildWindow(employeeEdit);
Затем включают прослушивания события закрытия окна.
winEmpEdit.Closed += new EventHandler(winEmpEdit_Closed);
Для дочернего формируется заголовок и окно выводится на экран дисплея.
winEmpEdit.Title = "Редактирование данных"; winEmpEdit.Show();
Обработка события закрытия дочернего окна реализуется методом winEmpEdit_Closed(), в котором по результату нажатия кнопки ОК проводят сохранение изменений в базе данных
employeeDomainDataSource.SubmitChanges();
а при нажатии кнопки Отмена – отмена проведенного редактирования данных
employeeDomainDataSource.RejectChanges();
Полный код обработчика winEmpEdit_Closed приводится ниже.
void winEmpEdit_Closed(object sender, EventArgs e) { EmployeeChildWindow emp = (EmployeeChildWindow)sender; if (emp.Employee != null) { if (emp.DialogResult == true) { employeeDomainDataSource.SubmitChanges(); } else { employeeDomainDataSource.RejectChanges(); } } }
При редактировании данных необходимо в списке выделить строку с данными, которые подлежат редактированию, нажать кнопку Редактирование для открытия Окна редактирования.
Для завершения редактирования нажимается кнопка ОК, а для отмены редактирования – кнопка Отмена.
Добавление данных в базу данных. Формирование новых данных можно выполнять с использованием созданного ранее дочернего окна EditEmployeeChildWindow. Для того, чтобы в коде можно было различать режимы в котором находится дочернее окно будем использовать свойство Tag окна. Так при формировании окна в режиме редактирования свойству Tag присвоим значение edit, а при добавлении нового сотрудника – new.
private void buttonNew_Click(object sender, RoutedEventArgs e) { Employee newEmployee= new Employee(); newEmployee.Role= "guest"; newEmployee.LastName= "не задано"; newEmployee.FirstName = "не задано"; newEmployee.SecondName = "не задано"; newEmployee.Email = "a@my.com"; newEmployee.Phone = "(999) 999-9999"; newEmployee.Inn = "999999999999"; newEmployee.TitleID = 1; newEmployee.FirstDate = DateTime.Now; EmployeeChildWindow winEmpEdit = new EmployeeChildWindow(newEmployee); winEmpEdit.Title = "Регистрация нового сотрудника"; winEmpEdit.Tag = "new"; winEmpEdit.Closed += new EventHandler(winEmpEdit_Closed); winEmpEdit.Show(); }
В методе buttonNew_Click() создается экземпляр класса Employee, задаются его поля, затем по аналогии с режимом редактирования данных, создается экземпляр дочернего окна EmployeeChildWindow, задаются его свойства, включается прослушивание события закрытия окна и оно выводится на экран.
Обработчик события закрытия окна изменен для использования его и для редактирования, и для создания новой записи.
void winEmpEdit_Closed(object sender, EventArgs e) { EmployeeChildWindow emp = (EmployeeChildWindow)sender; switch (emp.Tag.ToString()) { case "edit": if (emp.Employee != null) { if (emp.DialogResult == true) { employeeDomainDataSource.SubmitChanges(); } else { employeeDomainDataSource.RejectChanges(); } } break; case "new": if (emp.Employee != null) { if (emp.DialogResult == true) { EmployeeDomainContext employeeDomain = (employeeDomainDataSource.DomainContext) as EmployeeDomainContext; employeeDomain.Employees.Add(emp.Employee); employeeDomainDataSource.SubmitChanges(); } } break; } }
При создании новой записи по сотруднику используется метод Add сущности контекста домена службы DomainService и изменения в источнике данных фиксируются методом SubmitChanges().
Удаление данных из базы данных. Удаление записей реализуются в приложении методом buttonDelete_Click(), который является обработчиком события Click кнопки buttonDelete.
private void buttonDelete_Click(object sender, RoutedEventArgs e) { Employee emp = (Employee)(employeeDataGrid.SelectedItem); if (emp != null) { MessageBoxResult result = MessageBox.Show("Удалить данные", "Предупреждение", MessageBoxButton.OKCancel); if (result == MessageBoxResult.OK) { EmployeeDomainContext employeeDomain = (employeeDomainDataSource.DomainContext) as EmployeeDomainContext; employeeDomain.Employees.Remove(emp); employeeDomainDataSource.SubmitChanges(); } } }
Удаление данных из источника реализуется методом Remove(), которому в качестве параметра задается удаляемый объект.