При загрузке данных из БД возникает исключение InvalidOperationException с сообщением: Элемент коллекции должен быть пустым перед использованием ItemsSource. Знаю, что для заполнения DataGrid можно использовать коллекции Items или ItemsSource, но одновременно их использовать нельзя: если задано значение для свойства ItemsSource и в коде C# добавляется элемент в Items, возникает исключение. |
Разработка приложения на базе WPF
Цель
В процессе выполнения работы необходимо разработать страничное/оконное WPF приложение.
Задание 1. Создать проект в соответствии с шаблоном "приложение WPF" и разработать интерфейс пользователя – 1 час
Для разработки приложения необходимо создать WPF-проект ( рис. 6.1). В окне " Создать проект " необходимо проверить установку библиотеки .NET Framework 4 (1 – на рис. 6.1), выбрать шаблоны Windows (2 – на рис. 6.1), а среди имеющихся шаблонов задать Приложение WPF и в поле " Имя " ввести имя проекта WpfApplProject.
После нажатия кнопки "ОК" будет сформирован шаблон проекта. При этом инструментальная система сгенерирует следующий XAML-документ:
<Window x:Class="WpfApplProject.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> </Grid> </Window>
Дизайнер проекта приведен на рис. 6.2.
В приведенном XAML-документе имеется один элемент верхнего уровня <Window>. Дескриптор </Window> завершает весь документ. В XAML-документе приведено имя класса MainWindow
x:Class="WpfApplProject.MainWindow
два пространства имен
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
и три свойства:
Title="MainWindow" Height="350" Width="525"
Каждый атрибут соответствует определенному свойству класса Window. Приведенные атрибуты предписывают WPF создать окно с надписью MainWindow и размером 350х525 единиц. При компиляции и запуске проекта приложения на дисплей выводится окно, приведенное на рис. 6.3.
Когда выполняется компиляция приложения, XAML-файл, который определяет пользовательский интерфейс ( MainWindow.xaml ), транслируется в объявление типа CLR , которое объединяется с логикой приложения из файла класса отдельного кода ( MainWindow.xaml.cs ).
Метод InitializeComponent() генерируется во время компиляции приложения и в исходном коде не присутствует.
Для программного управления элементами управления, описанными в XAML-документе, необходимо задать XAML атрибут Name. Так для задания имени элементу Grid необходимо записать следующую разметку:
<Grid Name="grid"> </Grid>
Страницы приложения можно размещать внутри окон и внутри других страниц. В WPF при создании страничных приложений контейнером наивысшего уровня могут быть следующие объекты:
- NavigationWindow, который представляет собой несколько видоизмененную версию класса Window ;
- Frame, находящийся внутри другого окна или другой страницы;
- Frame, обслуживаемый непосредственно в Internet Explorer.
Для вставки страницы внутрь окна будем использовать класс Frame ( рис. 6.4). Автоматически будет сгенерирован экземпляр класса Frame с фиксированными границами рис. 6.5).
В XAML-документ проекта будет добавлена следующая строка:
<Frame Height="100" HorizontalAlignment="Left" Name="frame1" VerticalAlignment="Top" Width="200" />
С учетом того, что создается страничное приложение размеры фрейма не нужно фиксировать, поэтому изменим описание свойств фрейма:
<Frame Name="frame1" Margin="3" />
В результате фрейм заполнит всё окно ( рис. 6.6):
Созданный фрейм необходим для размещения в нем страницы WPF-приложения. Класс Page допускает наличие только одного вложенного элемента. Он не является элементом управления содержимым и наследуется от класса FrameworkElement. Класс Page имеет небольшой набор дополнительных свойств, которые позволяют настраивать его внешний вид, взаимодействовать с контейнером и использовать навигацию. Для перехода на другую страницу необходимо использовать навигацию.
Добавьте в проект начальную страницу. Для этого в Обозревателе решений щелкните правой кнопкой мыши на проекте WpfApplProject. В контекстном меню выберите пункт Добавить (1 – на рис. 6.8), а в раскрывающимся меню - пункт Страница (2 на рис. 6.7).
В окне Добавления нового элемента необходимо выбрать шаблон " Страница (WPF) " (1) и задать имя страницы PageMain (2 на рис. 6.8).
В дизайнере проекта сгенерируется страница PageMain.xaml ( рис. 6.9).
В сгенерированной странице в качестве контейнера верхнего уровня используется Grid. Замените Grid на контейнер StackPanel.
Главная страница приложения в дизайнере представлена на рис. 6.10.
Измените свойство Title окна класса Window, в соответствии с вариантом лабораторной работы.
Основная страница должна обеспечивать переход на другие страницы, обеспечивающие инферфейс для отдельных функций и выход из системы. Для перехода на другие страцицы используйте гиперссылки. Гиперссылки позволяют пользователю перемещаться с одной страницы на другую. Элемент гиперссылки, соответствующий объекту класса Hyperlink, определяется следующей строкой:
<Hyperlink >Текст Гиперссылки</Hyperlink>
Класс Hyperlink имеет свойство NavigateUri. Данное свойство определяет на какую страницу будет переходить приложение при щелчке на соответствующей гиперссылке. Например, NavigateUri="Page2.xaml".
В WPF гиперссылки являются не отдельными, а внутристроковыми потоковыми элементами, которые должны размещаться внутри другого поддерживающего их элемента. Это можно сделать, например в элементе TextBlock, который для гиперссылки является контейнером.
На первой странице создайте гиперссылки для перехода на страницы приложния, в соответствии в заданием.
Создание основного меню. Создайте основное меню с помощью класса Menu, который представляет Windows элементы управления меню, позволяющие иерархически организовать элементы, связанные с командами и обработчиками событий. Меню формируют из объектов MenuItem (имя пункта меню) и Separator (разделитель). Класс MenuItem имеет свойство Header, которое определяет текст элемента меню. Данный класс может хранить коллекцию объектов MenuItem, которая соответствует подпунктам меню. Класс Separator отображает горизонтальную линию, разделяющую пункты меню.
Добавьте в StackPanel страницы приложения 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>
Создание панели инструментов. Панель инструментов представляет специализированный контейнер для хранения коллекции элементов, обычно кнопок. Расположите в панели инструментов кнопки, функциональное назначение которых будет соответствовать подпунктам меню Действие, то есть Отменить, Создать, Редактировать, Сохранить, Найти и Удалить.
На лицевой стороне кнопок поместите графическое изображение соответствующего действия. Для этого добавьте в файл проекта папку Images и в неё включите графические объекты, которые можно найти в библиотеке графических объектов Visual Studio (папка VS2010ImageLibrary).
После добавления графических файлов в проект они будут отображены в обозревателе решений ( рис. 6.11).
Для каждой кнопки задайте свойство 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>
Проектирование интерфейсных элементов. При проектировании интерфейсных элементов для страницы приложения используются элементов контроля ListBox, ListView, TextBox, TextBlock, ComboBox, DataGrid и других.
Класс DataGrid представляет элемент управления, отображающий данные в настраиваемой сетке строк и столбцов. По умолчанию DataGrid автоматически создает столбцы, на основе источника данных. При этом генерируются следующие типы столбцов:
- DataGridTextColomn – для отображения в ячейках столбцов текстового содержимого;
- DataGridCheckBoxColomn – для отображения в ячейках столбцов логических данных;
- DataGridComboBoxColomn – для отображения в ячейках столбцов данных, когда имеется набор элементов для выбора;
- DataGridHyperlinkColomn – для отображения в ячейках столбцов элементов Uri.
Если разработчика не устраивает автоматическая генерация столбцов DataGrid можно её отключить. Для этого свойству AutoGenerateColumns необходимо присвоить значение false. Далее можно создать собственный набор столбцов ( Columns ), используя существующие типы столбцов или создать новый тип столбца с помощью шаблона DataGridTemplateColumn.
DataGrid поддерживает множество способов настройки отображения данных.