Опубликован: 08.07.2011 | Доступ: свободный | Студентов: 1772 / 93 | Оценка: 4.15 / 4.08 | Длительность: 15:28:00
Самостоятельная работа 1:

Разработка приложения на базе WPF

< Лекция 5 || Самостоятельная работа 1: 12345 || Лекция 6 >

Задание 2. Разработать бизнес-логику приложения – 2 часа.

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

Модель команд обеспечивает делегирование событий определенным командам и управление доступностью элементов управления в зависимости от состояния соответствующей команды. В WPF команда представляет собой задачу приложения и механизм слежения за тем, когда она может быть выполнена. В то же время сама команда не содержит конкретного кода выполнения задачи. Одна и та же команда может быть привязана к одному или нескольким интерфейсным элементам приложения. Инициируют команду источники, которые могут быть различными элементами управления, например пункты меню MenuItem или кнопки – Button. Целевым объектом команды является элемент, для которого предназначена эта команда.

Классы, реализующие команды должны поддерживать интерфейс ICommand. В этом интерфейсе определены два метода Execute, CanExecute и событие CanExecuteChanged.

public interface ICommand1
    {
        void Execute(object par);
        bool CanExecute(object par);
        event EventHandler CanExecuteChanged;
    }

Метод Execute может содержать код, реализующий бизнес-логику приложения. Метод CanExecute возвращает информацию о состоянии команды. Событие CanExecuteChanged вызывается при изменении состояния команды.

В WPF имеется библиотека базовых команд. Команды доступны через статические свойства следующих статических классов:

  • ApplicationCommands ;
  • NavigationCommands ;
  • EditingCommands ;
  • MediaCommands.

Для создания пользовательских команд целесообразно использовать классы RoutedCommand, который имеет реализацию интерфейса ICommand.

Для разработки пользовательских команд добавьте в проект папку Commands и в ней создайте класс DataCommands.

public class DataCommands
    {
        public static RoutedCommand Delete { get; set;}
        public static RoutedCommand Edit { get; set; }
        static DataCommands()
        {
            InputGestureCollection inputs = new InputGestureCollection();
            inputs.Add(new KeyGesture(Key.E, ModifierKeys.Control, "Ctrl+E"));
            edit = new RoutedCommand("Edit", typeof(DataCommands), inputs);
            inputs = new InputGestureCollection();
            inputs.Add(new KeyGesture(Key.D, ModifierKeys.Control, "Ctrl+D"));
            delete = new RoutedCommand("Delete", typeof(DataCommands), inputs);
        }
    }

В классе DataCommands объявлены два свойства Delete и Edit типа RoutedCommand. Класс RoutedCommand определяет команду, реализующую ICommand. В конструкторе данного класса определяется объект inputs типа InputGestureCollection. Класс InputGestureCollection представляет упорядоченную коллекцию объектов InputGesture, которые позволяют с помощью класса KeyGesture задать комбинацию клавиш для вызова команды.

Для использования страницей приложения пользовательских команд в XAML-документе необходимо добавить пространство имен, где расположен класс DataCommands. Данному пространству имен присвоим ссылку command.

xmlns:command="clr-namespace:WpfApplProject.Commands"

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

<Page.CommandBindings>
	<CommandBinding Command="Undo" 
	 Executed="UndoCommandBinding_Executed" 
        CanExecute="SaveCommandBinding_CanExecute" />
		... 
</Page.CommandBindings>

Для класса CommandBinding свойство Command определяет ссылку на соответствующую команду, а свойства Executed и CanExecute задают обработчики событий при выполнении команды.

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

  • первоначальная загрузка страницы;
  • просмотр данных;
  • редактирование данных;
  • создание новой записи.

В код программы класса страницы приложения введите логическое поле isDirty для управления доступностью команд.

private bool isDirty = true;

В код класса добавьте обработчики (реализация метода Executed ), определяющие бизнес-логику приложения. На данном этапе проектирования системы обработчики будут содержать только вывод сообщений о вызове команды и изменение поля isDirty. Код обработчика команды Удалить приведен ниже.

private void UndoCommandBinding_Executed(object sender, 
    ExecutedRoutedEventArgs e)
        {
            MessageBox.Show("Отмена");
            isDirty = true;
        }

В дальнейшем в обработчики необходима будет добавить код для обеспечения требуемой функциональности.

В коде класса необходимо добавить обработчики (реализация метода CanExecute ), которые управляют доступностью команд.

private void EditCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
   e.CanExecute = isDirty;
}
private void SaveCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
   e.CanExecute = !isDirty;
}

Необходимо модифицировать XAML-документ в части задания свойства Command при описании пунктов меню и панели инструментов для привязки команд.

При описании меню (Menu) XAML-документ модифицирован следующим образом.

<Menu>
    <MenuItem Header="Действие" BorderThickness="3" >
        <MenuItem Header="Отменить" Command="Undo"></MenuItem>
	... 
</Menu>

Соответствующие изменения XAML-документа необходимо провести и для панели инструментов ToolBar.

<ToolBar Name="ToolBar1" Margin="3">
     <Button Name="Undo" Margin="5,2,5,2" Command="Undo"
             ToolTip="Отменить редактирование/создание" >
         <Image Source="Images/Undo.jpg">
        </Image>
     </Button>
...
</ToolBar>
< Лекция 5 || Самостоятельная работа 1: 12345 || Лекция 6 >
Александр Петров
Александр Петров

При загрузке данных из БД возникает исключение 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 прописал все как положено, здесь похоже именно с преобразованием типов проблемы