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

Разработка Silverlight-приложений

Управление доступностью кнопок приложения

Silverlight не предлагает встроенную поддержку для модели команд WPF поэтому в разрабатываемом приложении функциональность, связанная с кнопками, должна реализовываться обработчиками событий, а доступность тех или иных кнопок управляться программно.

На странице приложения размещены шесть кнопок: Сохранить, Отменить, Создать, Загрузить, Редактировать и Удалить. Кнопки могут быть доступны или недоступны пользователю при работе приложения. Это задается свойством IsEnable. Доступность кнопок определяется состоянием, в котором находится приложение. В тоже время нажатие какой-либо кнопки переводит, как правило, приложение в какое-либо другое состояние. Для проектируемого приложения можно определить следующие состояния:

  • первоначальная загрузка страницы (1);
  • просмотр данных по всем сотрудникам (2);
  • редактирование данных по отдельному сотруднику (3);
  • создание новой записи по сотруднику в базе данных (4).

На рис. 7.16 приведена диаграмма состояний приложения, на которой кружками обозначены состояния, а дуги соответствуют переходам при нажатии определенной кнопки.

Диаграмма состояний приложения

Рис. 7.16. Диаграмма состояний приложения

На основе диаграммы состояний построим таблицу доступности кнопок в различных состояниях ( таблица 7.2).

Таблица 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;
    }
}
Александр Петров
Александр Петров

При загрузке данных из БД возникает исключение 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
Валентина Алешина
Валентина Алешина
Россия