|
При загрузке данных из БД возникает исключение InvalidOperationException с сообщением: Элемент коллекции должен быть пустым перед использованием ItemsSource. Знаю, что для заполнения DataGrid можно использовать коллекции Items или ItemsSource, но одновременно их использовать нельзя: если задано значение для свойства ItemsSource и в коде C# добавляется элемент в Items, возникает исключение. |
Взаимодействие приложения с базой данных
Редактирование, вставка и удаление данных
Для редактирования данных в приложении модифицируем метод EditCommandBinding_Executed
private void EditCommandBinding_Executed(object sender,
ExecutedRoutedEventArgs e)
{
DataGridEmployee.IsReadOnly = false;
DataGridEmployee.BeginEdit();
isDirty = false;
}Свойству IsReadOnly сетки DataGridEmployee присвоим значение false, что обеспечит возможность редактирования строк и ячеек сетки. Далее используем метод BeginEdit для начала редактирования ячейки, на которую наведен указатель мыши.
Результаты редактирования необходимо сохранить в базе данных. Для этого необходимо вызвать метод SaveCommandBinding_Executed.
private void SaveCommandBinding_Executed(object sender,
ExecutedRoutedEventArgs e)
{
DataEntitiesEmployee.SaveChanges();
isDirty = true;
DataGridEmployee.IsReadOnly = true;
}В методе SaveCommandBinding_Executed вызывается метод SaveChanges класса dataEntitiesEmployee. Метод SaveChanges сохраняет все обновления в источнике данных.
Для создания данных по новому сотруднику модифицируем метод NewCommandBinding_Executed.
private void NewCommandBinding_Executed(object sender,
ExecutedRoutedEventArgs e)
{
Employee employee = Employee.CreateEmployee(-1, "не задано",
"не задано", "не задано", 0);
employee.Telephone = "не задано";
employee.Email = "не задано";
try
{
DataEntitiesEmployee.Employees.AddObject(employee);
ListEmployee.Add(employee);
DataGridEmployee.ScrollIntoView(employee);
DataGridEmployee.SelectedIndex = DataGridEmployee.Items.Count - 1;
DataGridEmployee.Focus();
DataGridEmployee.IsReadOnly = false;
isDirty = false;
}
catch (DataServiceRequestException ex)
{
throw new ApplicationException(
"Ошибка добавления нового сотрудника в контекст данных" + ex.ToString());
}
}В методе NewCommandBinding_Executed объект employee класса Employee создается с помощью метода CreateEmployee, параметрами которого являются ID, которое задается равным -1, Surname, Name и Patronymic, которым задается значение "не задано" и TitleID со значением 0. Кроме того, свойствам Telephone и Email объекта employee присваивается строковое значение "не задано". В блоке try ... catch созданный объект employee добавляется в контекст данных методом AddObject сущности Employees EDM-модели DataEntitiesEmployee, а также в коллекцию ListEmployee. Затем производится прокрутка сетки, выделение и перемещение фокуса на созданный объект.
DataGridEmployee.ScrollIntoView(employee); DataGridEmployee.SelectedIndex = DataGridEmployee.Items.Count - 1; DataGridEmployee.Focus();
При инициализации команды создания данных по новому сотруднику в сетке формируется первоначальная строка с данными "по умолчанию" ( рис. 5.12). В сформированную строку необходимо ввести реальные данные сохранить их, вызвав команду "Сохранить".
Для удаления данных по сотруднику используем метод DeleteCommandBinding_Executed.
private void DeleteCommandBinding_Executed(object sender,
ExecutedRoutedEventArgs e)
{
Employee emp = DataGridEmployee.SelectedItem as Employee;
if (emp != null)
{
MessageBoxResult result = MessageBox.Show("Удалить сотрудника: " +
emp.Surname + " " +emp.Name + " " + emp.Patronymic,
"Предупреждение", MessageBoxButton.OKCancel);
if (result == MessageBoxResult.OK)
{
DataEntitiesEmployee.DeleteObject(emp);
DataGridEmployee.SelectedIndex =
DataGridEmployee.SelectedIndex == 0 ? 1 : DataGridEmployee.SelectedIndex - 1;
ListEmployee.Remove(emp);
DataEntitiesEmployee.SaveChanges();
}
}
else
{
MessageBox.Show("Выберите строку для удаления");
}
}В методе определяем объект emp класса Employee, который выделен в сетке DataGridEmployee.
Employee emp = DataGridEmployee.SelectedItem as Employee;
Если объект emp найден, то с помощью диалогового окна класса MessageBoxResult выводим сообщение с данными о сотруднике, которого предполагается удалить.
MessageBoxResult result = MessageBox.Show("Удалить сотрудника: " +
emp.Surname + " " + emp.Name + " " + emp.Patronymic, "Предупреждение", MessageBoxButton.OKCancel);При подтверждении операции удаления объект emp удаляется из контекста методом DeleteObject.
DataEntitiesEmployee.DeleteObject(emp);
Далее формируется в сетке DataGridEmployee выделяемая строка.
DataGridEmployee.SelectedIndex =
DataGridEmployee.SelectedIndex == 0 ? 1 : DataGridEmployee.SelectedIndex - 1;Объект emp удаляется из коллекции ListEmployee.
ListEmployee.Remove(emp);
Изменения вносятся в базу данных.
DataEntitiesEmployee.SaveChanges();
Страница PageEmployee при выполнении операции удаления данных по сотруднику приведена на рис. 5.13.
Метод UndoCommandBinding_Executed реализует отмену редактирования последних элементов сетки DataGridEmployee и переводит её в режим просмотра.
Для реализации данной функциональности необходимо провести некоторые изменения в коде приложения. Для метода Page_Loaded основной код выделим в метод GetEmployees.
private void GetEmployees()
{
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;
}С учетом созданного метода GetEmployees метод Page_Loaded будет иметь следующий вид.
private void Page_Loaded(object sender, RoutedEventArgs e)
{
GetEmployees();
DataGridEmployee.SelectedIndex = 0;
}Создадим метод RewriteEmployee, который будет обновлять контекст данных и коллекцию ListEmployee.
private void RewriteEmployee()
{
DataEntitiesEmployee = new TitlePresonalEntities();
ListEmployee.Clear();
GetEmployees();
}С учетом проведенных модификаций кода метод UndoCommandBinding_Executed будет иметь следующий вид.
private void UndoCommandBinding_Executed(object sender,
ExecutedRoutedEventArgs e)
{
RewriteEmployee();
DataGridEmployee.IsReadOnly = true;
isDirty = true;
}При запуске команды Отмена будет отменено редактирование в текущей ячейке сетки, а если редактировались несколько ячеек, то при повторном запуске команды будет обновлена вся строка.

