При загрузке данных из БД возникает исключение InvalidOperationException с сообщением: Элемент коллекции должен быть пустым перед использованием ItemsSource. Знаю, что для заполнения DataGrid можно использовать коллекции Items или ItemsSource, но одновременно их использовать нельзя: если задано значение для свойства ItemsSource и в коде C# добавляется элемент в Items, возникает исключение. |
Разработка Silverlight-приложений
Управление доступностью кнопок приложения
Silverlight не предлагает встроенную поддержку для модели команд WPF поэтому в разрабатываемом приложении функциональность, связанная с кнопками, должна реализовываться обработчиками событий, а доступность тех или иных кнопок управляться программно.
На странице приложения размещены шесть кнопок: Сохранить, Отменить, Создать, Загрузить, Редактировать и Удалить. Кнопки могут быть доступны или недоступны пользователю при работе приложения. Это задается свойством IsEnable. Доступность кнопок определяется состоянием, в котором находится приложение. В тоже время нажатие какой-либо кнопки переводит, как правило, приложение в какое-либо другое состояние. Для проектируемого приложения можно определить следующие состояния:
- первоначальная загрузка страницы (1);
- просмотр данных по всем сотрудникам (2);
- редактирование данных по отдельному сотруднику (3);
- создание новой записи по сотруднику в базе данных (4).
На рис. 7.16 приведена диаграмма состояний приложения, на которой кружками обозначены состояния, а дуги соответствуют переходам при нажатии определенной кнопки.
На основе диаграммы состояний построим таблицу доступности кнопок в различных состояниях ( таблица 7.2).
Состояние | Доступность кнопок - IsEnable | |||||
---|---|---|---|---|---|---|
Сохранить | Отменить | Создать | Загрузить | Редактировать | Удалить | |
1 | false | false | false | true | false | false |
2 | false | false | true | false | true | true |
3 | true | true | false | false | false | false |
4 | true | true | false | false | false | false |
В XAML-коде класса MainPage все кнопки определены как недоступные, то есть свойство IsEnable –false. После загрузки страницы (состояние 1) кнопка Загрузить становится доступной, а после загрузки данных из базы во всех остальных состояниях она недоступна. Режим доступности кнопок Сохранить, Отменить, Создать, Редактировать и Удалить в состояниях 2,3 и 4 изменяется в соответствии данными, приведенными в табл. 6.2. Для управления доступностью кнопок добавим в код класса MainPage метод ButtonIsEnabled().
private void ButtonIsEnabled(bool enabele) { ButtonEdit.IsEnabled = enabele; ButtonSave.IsEnabled = !enabele; ButtonNew.IsEnabled = enabele; ButtonUndo.IsEnabled = !enabele; ButtonDelete.IsEnabled = enabele; }
Кроме управления доступностью кнопок в приложении целесообразно управлять и возможностью редактирования детальных данных по сотруднику. Детальные данные должны быть доступны для редактирования в состояниях редактирования (3) и создания (4) новой записи, а в режиме просмотра – должны быть доступны только для чтения. Для управления доступностью детальных данных по сотруднику добавим в код класса MainPage метод ReadOnly().
private void ReadOnly(bool readOnly) { LastName1.IsReadOnly = !readOnly; FirstName1.IsReadOnly = !readOnly; SecondtName1.IsReadOnly = !readOnly; NetName1.IsReadOnly = !readOnly; comboBoxTitle.IsEnabled = readOnly; comboBoxAccess.IsEnabled = readOnly; comboBoxStatus.IsEnabled = readOnly; datePickerFirstDate.IsEnabled = readOnly; datePickerLastDate.IsEnabled = readOnly; }
В XAML-коде класса MainPage для кнопок Сохранить, Отменить, Создать, Редактировать и Удалить добавим событие Click и обработчики событий Save_Click(), Undo_Click(), New_Click(), Edit_Click() и Delete_Click().
<Button Name="ButtonSave" Content="Сохранить" Margin="5" Padding="5" Height="25" IsEnabled="False" Click="Save_Click" /> <Button Name="ButtonUndo" Content="Отменить" Margin="5" Padding="5" Height="25" IsEnabled="False" Click="Undo_Click"/> <Button Name="ButtonNew" Content="Создать" Margin="5" Padding="5" Height="25" IsEnabled="False" Click="New_Click"/> <Button Name="ButtonEdit" Content="Редактировать" Margin="5" Padding="5" Height="25" IsEnabled="False" Click="Edit_Click"/> <Button Name="ButtonDelete" Content="Удалить" Padding="5" Margin="35,0,0,0" Height="25" IsEnabled="False" Click="Delete_Click" />
При нажатии кнопки Удалить не изменяется состояние приложения – это видно из рис. 7.16, где действию Удалить соответствует петля для состояния 2, поэтому на текущем этапе разработки приложения не будем определять код метода и Delete_Click(), а для остальных созданных методов добавим код для управления доступности кнопок и элементов управления.
private void Save_Click(object sender, RoutedEventArgs e) { ReadOnly(false); ButtonIsEnabled(true); listBoxEmployees.IsEnabled = true; } private void Undo_Click(object sender, RoutedEventArgs e) { ReadOnly(false); ButtonIsEnabled(true); listBoxEmployees.IsEnabled = true; } private void Edit_Click(object sender, RoutedEventArgs e) { ButtonIsEnabled(false); listBoxEmployees.IsEnabled = false; ReadOnly(true); } private void New_Click(object sender, RoutedEventArgs e) { ButtonIsEnabled(false); ReadOnly(true); listBoxEmployees.IsEnabled = false; } private void Delete_Click(object sender, RoutedEventArgs e) { MessageBoxResult result = MessageBox.Show("Удалить сотрудника: " + emp.EmployeeSurname + " " + emp.EmployeeName + " " + emp.EmployeePatronymic, "Предупреждение", MessageBoxButton.OKCancel); if (result == MessageBoxResult.OK) { // Удалить выбранного сотрудника из коллекции данных } }
Кроме обработчиков событий кнопок необходимо внести изменения в код метода employees_LoadCompleted(), который завершает загрузку данных из базы по нажатию кнопки Загрузить.
private void employees_LoadCompleted(object sender, LoadCompletedEventArgs e) { if (e.Error == null) { if (employees.Continuation != null) { employees.LoadNextPartialSetAsync(); } else { listBoxEmployees.ItemsSource = employees; listBoxEmployees.UpdateLayout(); if (listBoxEmployees.Items.Count > 0) listBoxEmployees.SelectedIndex = 0; ButtonIsEnabled(true); ReadOnly(false); ButtonOpen.IsEnabled = false; } } else { MessageBox.Show(string.Format("An error has occured: {0}", e.Error.Message)); ButtonOpen.IsEnabled = true; } }