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

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

< Лекция 3 || Лекция 4: 1234 || Лекция 5 >

Навигация страничного приложения

Основная страница должна обеспечивать переход на другие страницы, обеспечивающие инферфейс для отдельных функций и выход из системы. Для перехода на другие страницы будем использовать гиперссылки. Гиперссылки позволяют пользователю перемещаться с одной страницы на другую. Элемент гиперссылки, соответствующий объекту класса Hyperlink, определяется следующей строкой:

<Hyperlink >Текст Гиперссылки</Hyperlink>

Класс Hyperlink имеет свойство NavigateUri. Данное свойство определяет на какую страницу будет переходить приложение при щелчке на соответствующей гиперссылке. Например, NavigateUri="Page2.xaml".

В WPF гиперссылки являются не отдельными, а внутристроковыми потоковыми элементами, которые должны размещаться внутри другого поддерживающего их элемента. Это можно сделать, например в элементе TextBlock, который для гиперссылки является контейнером.

На первой странице создадим следующие гиперссылки: Сотрудники, Клиенты, Договора, Ценные бумаги, Сделки и Справка. XAML-описание гиперссылки для страницы Сотрудники приведено ниже.

<TextBlock Margin="25,30,5, 5">
  <Hyperlink NavigateUri="PageEmployee.xaml">Сотрудники</Hyperlink>
</TextBlock>

Для реализации функциональности первого окна WPF-приложения осталось добавить кнопку выхода.

<Button Margin="25,15" Width="60" HorizontalAlignment="Left" 
Command="Close" >Выход</Button>

Результат компиляции и выполнения WPF-приложения приведен на рис. 4.12.

Начальная страница WPF-приложения с гиперссылками

увеличить изображение
Рис. 4.12. Начальная страница WPF-приложения с гиперссылками

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

Создадим страницу с именем PageEmployee. В качестве основного контейнера будем использовать панель StackPanel. Определим для неё градиентную заливку, аналогичную начальной странице приложения.

<Page x:Class="WpfApplProject.PageEmployee"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="600"
	Title="PageEmployee">
    <StackPanel Margin="3" Background="{StaticResource BackgroundWindowResource}">
    </StackPanel>

Страница PageEmployee должна обеспечивать пользователю просмотр данных по сотрудникам, ввод данных по новому сотруднику, редактирование, поиск и удаление данных. Доступ пользователя к функциональности системы будем предоставлять через различные меню.

Проектирование интерфейса

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

Основное меню создается с помощью класса Menu, который представляет Windows элементы управления меню, позволяющие иерархически организовать элементы, связанные с командами и обработчиками событий. Меню формируют из объектов MenuItem (имя пункта меню) и Separator (разделитель). Класс MenuItem имеет свойство Header, которое определяет текст элемента меню. Данный класс может хранить коллекцию объектов MenuItem, которая соответствует подпунктам меню. Класс Separator отображает горизонтальную линию, разделяющую пункты меню. Добавим в StackPanel страницы PageEmployee XAML- описание меню, которое на верхнем уровне будет содержать два пункта Действие и Отчет. Пункт Действие включает подпункты Отменить, Создать, Редактировать, Сохранить, Найти и Удалить. Между пунктами Отменить, Создать и пунктами Найти, Удалить добавлены разделительные линии.

<Menu>
    <MenuItem Header="Действие" >
        <MenuItem Header="Отменить" ></MenuItem>
        <Separator></Separator>
        <MenuItem Header="Создать" ></MenuItem>
        <MenuItem Header="Редактировать" ></MenuItem>
        <MenuItem Header="Сохранить" ></MenuItem>
        <MenuItem Header="Найти" />
        <Separator></Separator>
        <MenuItem Header="Удалить" ></MenuItem>
    </MenuItem>
    <MenuItem Header="Отчет"></MenuItem>
</Menu>

Запустим приложение и выберем ссылку Сотрудники на странице PageEmployee. При выборе пункта меню Действие появляется выпадающий список и пунктами подменю ( рис. 4.13).

Главное меню страницы PageEmployee

Рис. 4.13. Главное меню страницы PageEmployee

Панель инструментов представляет специализированный контейнер для хранения коллекции элементов, обычно кнопок. Расположим в панели инструментов кнопки, функциональное назначение которых будет соответствовать подпунктам меню Действие, то есть Отменить, Создать, Редактировать, Сохранить, Найти и Удалить.

На лицевой стороне кнопок поместим графическое изображение соответствующего действия. Для этого добавим в файл проекта папку Images и в неё включим графические объекты, которые можно найти в библиотеке графических объектов Visual Studio (папка VS2010ImageLibrary).

После добавления графических файлов в проект они будут отображены в обозревателе решений ( рис. 4.14).

Включение в проект папки Images с файлами рисунков

Рис. 4.14. Включение в проект папки Images с файлами рисунков

Теперь можно разработать XAML-описание панели инструментов для страницы PageEmployee.

Для каждой кнопки зададим свойство Nameимя объекта в программе и свойство ToolTip с текстом всплывающей подсказки при наведении указателя мыши на кнопку.

Свойство Margin определяет внешние отступы для кнопки. Задание графического объекта для кнопки осуществляется определением для объекта Image источника Source, который должен соответствовать полному пути к графическому файлу.

<ToolBar Name="ToolBar1" Margin="3">
<Button Name="Undo" ToolTip="Отменить редактирование/создание" 
Margin="5,2,5,2">
<Image Source="Images/Undo.jpg" />
 </Button>
	...
</ToolBar>

В дизайнере Visual Studio страница PageEmployee примет вид, приведенный на рис. 4.15.

Страниц PageEmployee с панелью инструментов в дизайнере

увеличить изображение
Рис. 4.15. Страниц PageEmployee с панелью инструментов в дизайнере

После запуска приложения и выборе кнопки панели инструментов Добавить ( Add ) страница PageEmployee будет иметь вид, приведенный на рис. 4.16.

Следующим шагом проектирования интерфейсных элементов для страницы PageEmployee является решение задачи формирования отображения данных по сотрудникам предприятия. Данная задача может быть решена различными способами: с помощью элементов контроля ListBox, ListView, TextBox, TextBlock, ComboBox, DataGrid и других.

Страница PageEmployee с панелью инструментов

Рис. 4.16. Страница PageEmployee с панелью инструментов

В учебном примере будем использовать элемент контроля DataGrid для табличного отображения данных о сотрудниках. В качестве заголовка таблицы применим текстовый блок "Список сотрудников".

Класс DataGrid представляет элемент управления, отображающий данные в настраиваемой сетке строк и столбцов. По умолчанию DataGrid автоматически создает столбцы, на основе источника данных. При этом генерируются следующие типы столбцов:

  • DataGridTextColumn – для отображения в ячейках столбцов текстового содержимого;
  • DataGridCheckBoxColomn – для отображения в ячейках столбцов логических данных;
  • DataGridComboBoxColomn – для отображения в ячейках столбцов данных, когда имеется набор элементов для выбора;
  • DataGridHyperlinkColomn – для отображения в ячейках столбцов элементов Uri.

Если разработчика не устраивает автоматическая генерация столбцов DataGrid можно её отключить. Для этого свойству AutoGenerateColumns необходимо присвоить значение false. Далее можно создать собственный набор столбцов ( Columns ), используя существующие типы столбцов или создать новый тип столбца с помощью шаблона DataGridTemplateColumn.

DataGrid поддерживает множество способов настройки отображения данных. В табл. 4.1 приведен список стандартных сценариев.

Таблица 4.1. Сценарии настройки отображения данных
Сценарий Подход
Переменные цвета фона Задайте для свойства AlternationIndex значение 2 или больше, а затем назначьте объект Brush свойствам RowBackground и AlternatingRowBackground.
Определение поведения при выборе ячейки и строки Установите свойства SelectionMode и SelectionUnit.
Настройка внешнего вида заголовков, ячеек и строк Примените новый Style к свойствам ColumnHeaderStyle, RowHeaderStyle, CellStyle или RowStyle.
Доступ к выбранным элементам Проверьте свойство SelectedCells, чтобы получить выделенные ячейки, и свойство SelectedItems, чтобы получить выбранные строки.
Настройка взаимодействия с пользователем Установите свойства CanUserAddRows, CanUserDeleteRows, CanUserReorderColumns, CanUserResizeColumns, CanUserResizeRows и CanUserSortColumns.
Отмена или изменение автоматически созданных столбцов Обработать событие AutoGeneratingColumn.
Заморозка столбца Задайте для свойства FrozenColumnCount значение 1 и переместите столбец в крайнюю левую позицию, задав для свойства DisplayIndex значение 0.
В качестве источника данных используются данные XML. Привяжите ItemsSource в DataGrid к запросу XPath, представляющему коллекцию элементов. Создайте каждый столбец в DataGrid. Свяжите каждый столбец, указав XPath для привязки к запросу, который получает свойство из источника элемента.

XAML-документ описания интерфейсных элементов страницы PageEmployee имеет следующий вид.

<TextBlock Margin="5" >Список сотрудников</TextBlock>
<DataGrid Name="DataGridEmployee" >
    <DataGrid.Columns>
        <DataGridTextColumn Header="Фамилия"/>
	.	.	.
        <DataGridComboBoxColumn Header="Должность" />
        <DataGridTemplateColumn Header="Дата рождения" />
	. . .
    </DataGrid.Columns>
</DataGrid>

Для полей Фамилия, Имя, Отчество, Телефон и Электронная почта используется тип столбца DataGridTextColumn. Так как должность сотрудника задается в соответствии с данными из справочника базы данных, то есть предоставляется список, из которого можно произвести выбор, для данного столбца используется тип DataGridComboBoxColumn. Для столбца Дата рождения используется специфичный шаблон, то есть тип DataGridTemplateColumn, который будет описан позднее.

С учетом добавленных интерфейсных элементов страница PageEmployee в дизайнере примет вид, приведенный на рис. 4.17.

Страница PageEmployee с элементом DataGrid в дизайнере

увеличить изображение
Рис. 4.17. Страница PageEmployee с элементом DataGrid в дизайнере

После запуска приложения страница PageEmployee будет иметь вид, приведенный на рис. 4.18

Страница PageEmployee с элементом DataGrid

Рис. 4.18. Страница PageEmployee с элементом DataGrid

На данном этапе проектирования приложения на странице PageEmployee размещены все необходимые элементы контроля.

< Лекция 3 || Лекция 4: 1234 || Лекция 5 >
Александр Петров
Александр Петров

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