- •Java и c# технологии прикладного програмирования
- •Java и c# технологии прикладного програмирования
- •Содержание
- •Введение
- •Лабораторная работа № 1 Коллекции c#
- •Цель работы
- •Теоретические сведения
- •Общие сведения о платформе .Net
- •Общие сведения о коллекциях c#
- •Обобщенные коллекции с#
- •Порядок выполнения лабораторной работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Получение информации о типе
- •Экземпляр типа Type
- •Получение экземпляра типа Type
- •Динамическая загрузка сборок
- •Динамическая загрузка типов
- •Исследование типа
- •Характеристики типа как целого
- •Члены класса
- •Динамическое создание объекта и вызов методов
- •Создание объекта по его типу
- •Динамический вызов методов
- •Использование интерфейсов
- •Позднее связывание
- •Динамическое приведение типов
- •Новые механизмы абстракции
- •Динамическое создание типов
- •Динамическое создание программного кода
- •Динамическое создание класса
- •Динамическое создание перечислений
- •Динамический "Hello World!"
- •Динамическое разворачивание циклов
- •Атрибуты
- •Атрибут это класс
- •Декларативное программирование
- •Код, выполняемый во время разработки
- •Использование атрибутов
- •Использование встроенных атрибутов
- •Определение и использование пользовательских атрибутов
- •Пример декларативного программирования
- •Порядок выполнения работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Связный уровень взаимодействия ado.Net
- •Несвязный уровень взаимодействия ado.Net
- •Порядок выполнения работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Связи между объектами в FluentNHibernate
- •Связь один к одному
- •Связь один ко многим
- •Связь многие ко многим
- •Способы выборки объектов в FluentNHibernate
- •Запросы NativeSql
- •Запросы по критерию
- •Запросы по образцу
- •Запросы hql
- •Порядок выполнения работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Компиляция страниц по требованию
- •Страница asp.Net 2.0
- •Директива @Page
- •Жизненный цикл страницы
- •Новые свойства и методы объекта Page
- •Управление страницей
- •Установка выделения на элемент управления
- •Обновление данных без перезагрузки страницы
- •Отправка данных формы другой странице asp.Net
- •Шаблоны дизайна страниц
- •Создание шаблона дизайна
- •Создание страницы
- •Обработка шаблонов средой asp.Net
- •Использование разных шаблонов для разных браузеров
- •Порядок выполнения работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Библиотеки модульного тестирования в .Net
- •Unit Testing Framework от Microsoft
- •Порядок выполнения работы
- •Задание на лабораторную работу
- •Содержание отчета
- •Контрольные вопросы
- •Рекомендованная литература
Порядок выполнения работы
В данном порядке выполнения лабораторной работы будет описано создание WEB-приложения, вфункции которого входит отображение, добавление, удаление и редактирование групп, отображение, добавление, удаление и редактирование студентов в группе. В качестве источника данных, как и в предыдущей лабораторной работе, будет использоваться СУБДPostgreSQLи созданный вппредыдущей лабораторной работе слой доступа к данным.
Создайте новый проект Веб-приложение ASP.NET(нажмите «Файл», «Создать», «Проект», в появившемся окне выберите «Web», «Веб-приложениеASP.NET», задайте каталог проекта и имя проекта, напримерlab5).
Добавьте в каталог с проектом библиотеки для работы с СУБД PostgreSQL, библиотекиNHibernateи библиотекиFluentNHibernate. Данные библиотеки можно скачать по ссылкам:
Драйвер к postgreSQL |
http://www.postgresql.org/ |
Библиотеки NHibernate |
http://sourceforge.net/projects/nhibernate/ |
Библиотеки Fluent NHibernate |
http://fluentnhibernate.org/ |
В данном проекте были использованы архивы:
Npgsql2.0.10-bin-ms.net.zip
NHibernate-2.1.2.GA-bin.zip
fluentnhibernate-1.1.zip
Список всех необходимых библиотек приведен ниже:
-
Npgsql.dll
Mono.Security.dll
NHibernate.dll
Antlr3.Runtime.dll
Iesi.Collections.dll
log4net.dll
Castle.DynamicProxy2.dll
Castle.Core.dll
NHibernate.ByteCode.Castle.dll
FluentNHibernate.dll
Подключите библиотеки Npgsql.dll, NHibernate.dll, FluentNHibernate.dll и NHibernate.ByteCode.Castle к проекту (нажмите правой кнопкой на «Ссылки» в дереве объектов потом на «Добавить ссылку…», перейдите на закладку «Обзор», выберите необходимые файлы).
Добавьте в проекте каталоги dao, domain, img,mapping.Каталоги dao, domain,mapping будут использоваться для хранения классов слоя доступа к даннымDAO, реализованного в предыдущей лабораторной работе, а каталогimgбудет использоваться для хранения изображений приложения.
Каталоги dao, domain, img,mappingв обозревателе решений изображены на рисунке 5.1.
Рисунок 5.1 – Каталоги dao, domain, img,mappingв обозревателе решений
Скопируйте классы слоя доступа к данным, созданные в предыдущей лабораторной работке в соответствующие каталоги WEB-приложения. Это можно сделать, например, с использованием файлового менеджераTotalCommander.
Откройте каталог daoс предыдущей лабораторной работы и скопируйте все классы в каталогdaoпроектаWEB-приложения. Результаты копирования представлены на рисунке 5.2.
Рисунок 5.2 – Результаты копирования классов с каталога daoпредыдущего проекта в каталогdaoWEB-приложения
Классы каталогов domainиmappingтаким же образом необходимо скопировать в соответствующие каталогиWEB-приложения.
После копирования классов в проекте они не появятся, поэтому их следует добавить в проект (нажмите правой кнопкой мыши на каталог daoи в контекстном меню выберете пункт «Добавить», «Существующий элемент», в открывшемся диалоге выберете все классы каталогаdaoWEB-приложения и нажмите «Добавить»). Те же действия произведите с классами каталоговdomainиmapping. В проекте должны появиться все классы слоя доступа к данным. Результат представлен на рисунке 5.3.
Рисунок 5.3 – Результат добавления классов слоя доступа к данным
Таким образом, все классы слоя доступа к данным были перенесены в WEB-приложение, и их можно использовать для отображения, добавления, удаления, замены данных.
Приступим к реализации интерфейса нашего WEB-приложения. Он у нас будет состоять из двух страниц. На одной странице будет отображаться список групп, а по нажатию на группу на второй будет отображаться список студентов группы. Эти страницы будут однотипными, у каждой из них будет шапка с названием страницы, футер (нижняя часть страницы) и меню. В данном случае страниц всего две, но в реальных проектах их может быть намного больше и те части, которые являются для группы страниц однотипными лучше выносить в шаблон страницы.
Создадим шаблон страницы для WEB-приложения. Нажмите правой кнопкой мыши на проект, нажмите «Добавить», затем «Создать элемент», в появившемся диалоге выберете «Web», затем «Главная страница», введите имя шаблона страницы, напримерUniversity и нажмите «Добавить».
Откройте шаблон страницы Universityс помощью редактора главных страниц (нажмите правой кнопкой на шаблон страницыUniversity, выберете «Открыть с помощью», в открывшемся диалоге выберете «Редактор главных страниц (По умолчанию)»). Откроется код шаблона главной страницы, который обычно состоит изhtmlтегов и из теговASP.NET. Шаблон главной страницы можно редактировать как в текстовом, так и графическом режиме, перетаскивая необходимые элементы с палитры компонентов,html-теги чаще всего используются для разметки страницы. Неотъемлемым тегом шаблона страницы является тег:
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
Вместо этого тега на страницах, которые наследуют шаблон страницы, подставляется необходимое содержимое.
Спроектируем шаблон страницы в графическом режиме.
Откройте шаблон страницы Universityс использованием графического редактора (нажмите два раза на шаблон страницы и из трех возможных вариантов «Конструктор», «Разделить», «Исходный код» выберите «Конструктор»). Для разметки страницы будем использовать таблицы.
Откройте палитру компонентов, разместите в верхней части шаблона страницы три компонент Tableс разделаHTML. Один компонент будет использоваться для размещенияheader(верхней части страницы), второй компонент будет использоваться для размещения основной части страницы, а третий будет использоваться для размещенияfooter(нижней части страницы). Таблицы по умолчанию создаются с тремя рядками и тремя колонками и их необходимо настроить соответствующим образом.
Настроим header(верхнюю часть) шаблона. Для верхней таблицы из трех добавлены таблицы установите количество колонок равным 2, а количество строк равным 1. К сожалению, этого нельзя сделать с помощью диспетчера свойств, а только в текстовом режиме, поэтому шаблон страницы необходимо открыть в текстовом режиме и удалите лишние теги <tr> и <td>.
В результате получится код таблицы:
<table style="width:100%;">
<tr>
<td>
</td>
<td>
</td>
</tr>
</table>
В левую колонку верхней таблицы вставьте компонент Imageс раздела «Стандартный», а в правую колонку вставьте компонентLabelс того же самого раздела. Выберите для компонентаImageизображение, поместите его в каталогеimg. Установите с помощью диспетчера свойствURLизображения (свойствоImageUrl). Установите свойствоTextу компонентаLabel– это будет текст заголовкаWEB-приложения. Окончательный вариант верхней таблицы в текстовом виде представлен ниже:
<table style="width:100%;" cellpadding="0" cellspacing="0">
<tr>
<td width="200">
<asp:Image ID="Image1" runat="server" ImageUrl="~/img/1.png" />
</td>
<td align="center" bgcolor="#8B0000">
<asp:Label ID="Label1" runat="server" Font-Bold="True" Font-Size="20pt"
Text="Черниговский государственный технологический университет"
ForeColor="#EEC900">
</asp:Label>
</td>
</tr>
</table>
Как видно из текста таблицы, для первой колони, устанавливается ширина по размеру изображения, а для второй колонки устанавливается цвет заливки и выравнивание по центру.
Приступим к реализации центральной части страницы, представленной центральной таблицей. Центральная таблица также должна состоять из одной строчки и двух колонок. В левой колонке будет размещаться меню приложения, но оно в данном примере использоваться не будет, поскольку приложение состоит всего лишь с двух страниц, поэтому мы только расположим меню в левой колонке, заполним названия пунктов меню, а адреса страниц, на которые необходимо переходить при нажатии на пункты меню заполнять не будем. Как удалять лишние колонки и строки, показано в предыдущем пункте данного руководства. Разместите в левой колонке компонент Menuс раздела «Переходы». В правую колонку перетяните компонент ContentPlaceHolder, который на данный момент размещается под всеми таблицами. Текст центральной таблицы представлен ниже:
<table style="width:100%;">
<tr>
<td width="200" valign="top">
<table style="width:100%;">
<tr>
<td align="left">
<asp:Label ID="Label2" runat="server" Text="МЕНЮ"
Font-Size="16pt" ForeColor="Maroon">
</asp:Label>
</td>
</tr>
<tr>
<td>
<asp:Menu ID="Menu1" runat="server"
Font-Size="16pt" ForeColor="Maroon">
<Items>
<asp:MenuItem Text="Группы" Value="Группы">
</asp:MenuItem>
<asp:MenuItem Text="Студенты" Value="Студенты">
</asp:MenuItem>
</Items>
</asp:Menu>
</td>
</tr>
</table>
</td>
<td>
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</td>
</tr>
</table>
Как видно из текста таблицы, левая колонка для удобства разбита на две части еще одной таблицей, в верхней части располагается компонент Labelсо словомMenu, в нижній располагается самом меню.
Приступим к реализации нижней части страницы, представленной нижней таблицей. Она будет состоять с двух строк и одной колонки. В первой строке будет размещаться линия разделения футера от основной части страницы, а во второй строке будет размещаться футер страницы. Текст нижней таблицы приведен ниже:
<table style="width:100%;">
<tr>
<td>
<hr style="color: #800000" />
</td>
</tr>
<tr>
<td align="center">
<asp:Label ID="Label3" runat="server"
Text="OrIoN (c)" ForeColor="Maroon">
</asp:Label>
</td>
</tr>
</table>
Полный текст шаблона страницы приведен ниже, а внешний вид шаблона страницы приведен на рисунке 5.4.
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="University.master.cs" Inherits="lab5.University" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Черниговский государственный технологический университет</title>
</head>
<body>
<form id="form1" runat="server">
<table style="width:100%;" cellpadding="0" cellspacing="0">
<tr>
<td width="200">
<asp:Image ID="Image1" runat="server" ImageUrl="~/img/1.png" />
</td>
<td align="center" bgcolor="#8B0000">
<asp:Label ID="Label1" runat="server"
Font-Bold="True" Font-Size="20pt"
Text="Черниговский государственный технологический университет"
ForeColor="#EEC900">
</asp:Label>
</td>
</tr>
</table>
<table style="width:100%;">
<tr>
<td width="200" valign="top">
<table style="width:100%;">
<tr>
<td align="left">
<asp:Label ID="Label2" runat="server"
Text="МЕНЮ" Font-Size="16pt"
ForeColor="Maroon">
</asp:Label>
</td>
</tr>
<tr>
<td>
<asp:Menu ID="Menu1" runat="server"
Font-Size="16pt" ForeColor="Maroon">
<Items>
<asp:MenuItem Text="Группы" Value="Группы">
</asp:MenuItem>
<asp:MenuItem Text="Студенты"
Value="Студенты">
</asp:MenuItem>
</Items>
</asp:Menu>
</td>
</tr>
</table>
</td>
<td>
<asp:ContentPlaceHolder ID="ContentPlaceHolder1"
runat="server">
</asp:ContentPlaceHolder>
</td>
</tr>
</table>
<table style="width:100%;">
<tr>
<td>
<hr style="color: #800000" />
</td>
</tr>
<tr>
<td align="center">
<asp:Label ID="Label3" runat="server" Text="OrIoN (c)"
ForeColor="Maroon"></asp:Label>
</td>
</tr>
</table>
</form>
</body>
</html>
Рисунок 5.4 – Внешний вид шаблона страницы
Шаблон страницы удобно использовать для инициализации сессии NHibernate. ОткройтеC#код шаблона страница. Каждая страница в том числе и шаблоныв ASP.NETобязательно содержат С# код, открыть который можно раскрыв дерево, узлом которого является страницы. Если шаблон страницы называется University.Master, то егоC#код будет называться University.Master.cs. Добавьте над методом Page_Load, который создается автоматически поля:
private ISessionFactory factory;
private ISession session;
За методом добавьте два вспомагательные метода:
//Метод открытия сессии
private ISession openSession(String host, int port, String database,
String user, String passwd)
{
ISession session = null;
//Получение ссылки на текущую сборку
Assembly mappingsAssemly = Assembly.GetExecutingAssembly();
if (factory == null)
{
//Конфигурирование фабрики сессий
factory = Fluently.Configure()
.Database(PostgreSQLConfiguration
.PostgreSQL82.ConnectionString(c => c
.Host(host)
.Port(port)
.Database(database)
.Username(user)
.Password(passwd)))
.Mappings(m => m.FluentMappings
.AddFromAssembly(mappingsAssemly))
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
}
//Открытие сессии
session = factory.OpenSession();
return session;
}
//Метод для автоматического создания таблиц в базе данных
private static void BuildSchema(Configuration config)
{
//new SchemaExport(config).Create(false, true);
}
Добавьте обработчик события Page_Init:
protected void Page_Init(object sender, EventArgs e)
{
session = openSession("localhost", 5432,
"university", "postgres", "111111");
Session["hbmsession"] = session;
}
Обработчик события Page_Init вызывается при инициализации страницы, в этот момент и создается сессияNHibernate, которая помещается в объектSession – объект способный хранить необходимы данные, пока активна HTTP-сессия с приложением. Как видно из текста обработчика события Page_Init, настройки подключения к базе прописаны в коде программы, чего делать нежелательно. Все настройки приложения, в том числе и настройки подключения к базе должны храниться в специальном файлеWeb.config.
Наш шаблон готов и теперь мы можем использовать его для оформления наших страниц.
Приступим к реализации главной страницы, на которой будет располагаться список групп. Необходимо будет реализовать такие функции как добавление, удаление замена данных о группах, а также отображение списка студентов группы.
Страница Default.aspx– стартовая страница приложения – создалась в проекте автоматически, ее мы и будем использовать как страницу для отображения списка групп.
Откройте Default.aspxв режиме исходного кода. Удалите весь исходный код кроме первой строчки:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="lab5._Default"%>
Вставьте тег <asp:Content> и підключите к странице Default.aspx шаблон страницы:
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1"
runat="server">
</asp:Content>
Начальный код страницы должен выглядеть следующим образом:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="lab5._Default" MasterPageFile="~/University.Master"%>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1"
runat="server">
</asp:Content>
Никаких тегов <html>, <body>, <form> на странице быть не должно. Если страница использует шаблон страницы, во все эти теги уже присутствуют в шаблоне.
Переходим к визуальному проектированию страницы Default.aspx. Откройте станицу в режиме исходного кода. Если шаблон был подключен правильно, то страница будет состоять из компонентов расположенных в шаблоне и из компонента, в который можно помещать содержимое текущей страницы. Разметку страницы, как и в шаблоне, будем производить с использованием таблиц.
Вставьте в редактируемую часть страницы таблицу, состоящую из одной колонки и двух рядков. В первом рядке будет отображаться название таблицы, а во втором рядке поместите компонент GridView с раздела «Данные». Этот компонент имеет ряд достоинств и недостатков. Так, например, он удобен для редактирования и удаления записей, но очень неудобен для добавления данных. Компонент GridView способен реагировать на ряд событий,таких как:
RowEditing – возникает, когда строка таблицы переводится в режим редактирования;
RowUpdating– возникает при нажатии на кнопкуUpdateредактируемой строки;
RowDeleting– возникает при нажатии на кнопкуDelete;
RowCancelingEdit– возникает при отмене редактирования строки;
RowCommand– это событие возникает при нажатии кнопок, размещенных в строчке таблицы;
PageIndexChanging– возникает при изменении индекса страницы GridView, если настроено постраничное отображение;
Исходный код страницы Default.aspx приведен ниже:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="lab5._Default" MasterPageFile="~/University.Master"%>
<asp:Content ID="Content1"
ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<table align="center">
<!—Строка названия таблицы-->
<tr align="center">
<td>
<asp:Label ID="Label4" runat="server" Text="Список групп"
Font-Size="20pt" ForeColor="Maroon" Font-Bold="True"/>
</td>
</tr>
<!—-Строка, содержащая таблицу для отображения списка групп-->
<tr>
<td>
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="false"
ShowFooter="true" ShowHeader="true"
AllowPaging="true" PageSize="10"
onrowdeleting="GridView1_RowDeleting" Font-Size="14pt"
onrowediting="GridView1_RowEditing"
onrowcancelingedit="GridView1_RowCancelingEdit"
onpageindexchanging="GridView1_PageIndexChanging"
HorizontalAlign="Center"
onrowupdating="GridView1_RowUpdating"
onrowcommand="GridView1_RowCommand" >
<Columns>
<!—-Шаблон колонки для названия группы-->
<asp:TemplateField HeaderText="Название группы"
ItemStyle-Width="200">
<ItemTemplate>
<asp:Label id="myLabel1" runat="server"
Text='<%# Bind("GroupName")%>' />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="myTextBox1" runat="server" Width="200"
Text='<%# Bind("GroupName") %>'/>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="myFooterTextBox1" runat="server"
Width="200" Text='<%# Bind("GroupName") %>' />
</FooterTemplate>
</asp:TemplateField>
<!—-Шаблон колонки для ФИО куратора -->
<asp:TemplateField HeaderText="ФИО куратора"
ItemStyle-Width="300">
<ItemTemplate>
<asp:Label id="myLabel2" runat="server"
Text='<%# Bind("CuratorName")%>' />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="myTextBox2" runat="server" Width="300"
Text='<%# Bind("CuratorName") %>'/>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="myFooterTextBox2" runat="server" Width="300"
Text='<%# Bind("CuratorName") %>' />
</FooterTemplate>
</asp:TemplateField>
<!—-Шаблон колонки для ФИО старосты-->
<asp:TemplateField HeaderText="ФИО старосты"
ItemStyle-Width="300">
<ItemTemplate>
<asp:Label id="myLabel3" runat="server"
Text='<%# Bind("HeadmanName")%>' />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="myTextBox3" runat="server" Width="300"
Text='<%# Bind("HeadmanName") %>'/>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="myFooterTextBox3" runat="server"
Width="300" Text='<%# Bind("HeadmanName") %>' />
</FooterTemplate>
</asp:TemplateField>
<!—-Шаблон командной колонки-->
<asp:TemplateField HeaderText="Команды" ItemStyle-
HorizontalAlign="Center" FooterStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:ImageButton ID="ibEdit" runat="server"
CommandName="Edit" Text="Edit"
ImageUrl="~/img/6.png" />
<asp:ImageButton ID="ibDelete" runat="server"
CommandName="Delete" Text="Delete"
ImageUrl="~/img/3.png" />
<asp:ImageButton ID="lbSelect" runat="server"
CommandName="Select"
ImageUrl="~/img/4.png"
CommandArgument='<%# Container.DataItemIndex %>'/>
</ItemTemplate>
<EditItemTemplate>
<asp:ImageButton ID="ibUpdate" runat="server"
CommandName="Update" Text="Update"
ImageUrl="~/img/5.png" />
<asp:ImageButton ID="ibCancel" runat="server"
CommandName="Cancel" Text="Cancel"
ImageUrl="~/img/7.png" />
</EditItemTemplate>
<FooterTemplate>
<asp:ImageButton ID="ibInsert" runat="server"
CommandName="Insert" OnClick="ibInsert_Click"
ImageUrl="~/img/2.png" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
<!—-Шаблон для отображения таблицы с пустыми данными-->
<EmptyDataTemplate>
<table border="1" cellpadding="0" cellspacing="0">
<tr>
<td width="200" align="center">Название группы</td>
<td width="300" align="center">ФИО куратора</td>
<td width="300" align="center">ФИО старосты</td>
<td>Команды</td>
</tr>
<tr>
<td>
<asp:TextBox ID="emptyGroupNameTextBox" runat="server"
Width="200"/>
</td>
<td>
<asp:TextBox ID="emptyCuratorNameTextBox" runat="server"
Width="300"/>
</td>
<td>
<asp:TextBox ID="emptyHeadmanNameTextBox" runat="server"
Width="300"/>
</td>
<td align="center">
<asp:ImageButton ID="emptyImageButton" runat="server"
ImageUrl="~/img/2.png"
OnClick="ibInsertInEmpty_Click"/>
</td>
</tr>
</table>
</EmptyDataTemplate>
<PagerStyle HorizontalAlign ="Center" />
</asp:GridView>
</td>
</tr>
</table>
</asp:Content>
Таблица состоит из колонок, размещенных в теге <Columns>. Для каждой колонки определен шаблон из трех частей. В первой части шаблона описывается, как будет выглядеть элемент строки в обычном состоянии. Во второй части шаблона описывается, как будет выглядеть элемент строки таблицы в режиме редактирования. В третьей части шаблона описывается, как будет выглядеть футер таблицы.
Поскольку компонент GridViewпри отсутствии данных в источнике данных не отображается нато его внешний вид при отсутствии данных необходимо описать с использование тега <EmptyDataTemplate>.
Для каждой кнопки таблицы необходимо выбрать изображение и поместить его в каталог img.
Далее необходимо реализовать обработчики событий по нажатия на кнопки компонента GridView.
Откройте C#код страницы Default.aspx. Поскольку все функции нашего приложения, которые нам необходимо запрограммировать будут использовать сессиюNHibernate, то в первую получить сессиюNHibernatecобъектаSession.
Добавьте обработчик события Page_Prerender после пустого обработчика событий Page_Load:
protected void Page_Prerender(object sender, EventArgs e)
{
ISession session = (ISession)Session["hbmsession"];
DAOFactory factory = new NHibernateDAOFactory(session);
IGroupDAO groupDAO = factory.getGroupDAO();
List<Group> groups = groupDAO.GetAll();
GridView1.DataSource = groups;
GridView1.DataBind();
}
В этом обработчике из объекта Session происходит получение сессии NHibernate.
Далее необходимо реализовать функцию добавления группы. Поскольку компонент GridViewне отображает данные при пустом источнике данных и кнопка добавления данных при непустом источнике данных и при пустом источнике данных – это две разные кнопки, то необходимо реализовывать два разных обработчика событий нажатия на кнопку добавить.
Ниже приведен код для обработчиков нажатия на кнопку «Добавить» для пустого и непустого источника данных:
//Обработчик нажатия на добавить
protected void ibInsert_Click(object sender, EventArgs e)
{
//Получаем значения полей
string s1 =
((TextBox)GridView1.FooterRow.FindControl("MyFooterTextBox1")).Text;
string s2 =
((TextBox)GridView1.FooterRow.FindControl("MyFooterTextBox2")).Text;
string s3 =
((TextBox)GridView1.FooterRow.FindControl("MyFooterTextBox3")).Text;
//Создаем группу
Group group = new Group();
group.GroupName = s1;
group.CuratorName = s2;
group.HeadmanName = s3;
//Создаем DAO группы
ISession session = (ISession)Session["hbmsession"];
DAOFactory factory = new NHibernateDAOFactory(session);
IGroupDAO groupDAO = factory.getGroupDAO();
groupDAO.SaveOrUpdate(group);
Response.Redirect(HttpContext.Current.Request.Url.ToString());
}
//Добавление первой записи в пустой GridView
protected void ibInsertInEmpty_Click(object sender, EventArgs e)
{
var parent = ((Control)sender).Parent;
var groupNameTextBox = parent
.FindControl("emptyGroupNameTextBox") as TextBox;
var curatorNameTextBox = parent
.FindControl("emptyCuratorNameTextBox") as TextBox;
var headmanNameTextBox = parent
.FindControl("emptyHeadmanNameTextBox") as TextBox;
Group group = new Group();
group.GroupName = groupNameTextBox.Text;
group.CuratorName = curatorNameTextBox.Text;
group.HeadmanName = headmanNameTextBox.Text;
ISession session = (ISession)Session["hbmsession"];
DAOFactory factory = new NHibernateDAOFactory(session);
IGroupDAO groupDAO = factory.getGroupDAO();
groupDAO.SaveOrUpdate(group);
Response.Redirect(HttpContext.Current.Request.Url.ToString());
}
Далее необходимо реализовать функцию удаления группы. Удаление группы происходит по событию RowDeleting, обработчик которого приведен ниже:
//Удаление записи
protected void GridView1_RowDeleting(object sender,
GridViewDeleteEventArgs e)
{
//Получить индекс выделенной строки
int index = e.RowIndex;
GridViewRow row = GridView1.Rows[index];
//Получить название группы
string key = ((Label)(row.Cells[0].FindControl("myLabel1"))).Text;
//Создание DAO группы
ISession hbmSession = (ISession)Session["hbmsession"];
DAOFactory factory = new NHibernateDAOFactory(hbmSession);
IGroupDAO groupDAO = factory.getGroupDAO();
//Получение группы по имени
Group group = groupDAO.getGroupByName(key);
//Удаление группы
if (group != null)
{
groupDAO.Delete(group);
}
Response.Redirect(HttpContext.Current.Request.Url.ToString());
}
Далее необходимо реализовать функцию редактирования записи. Строка компонента GridViewможет пребывать в обычном состоянии и в режиме редактирования. В обычном состоянии в командной колонке отображаются кнопки «Редактировать» и «Удалить», а в режиме редактирования отображаются кнопки «Обновить» и «Отменить». В процессе редактирования записи учувствует три кнопки «Редактировать», «Обновить» и «Отменить» и необходимо реализовать обработчики событий нажатия на эти кнопки. Ниже приведен код обработчиков:
//Перевести строку в режим редактирования
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
//Получить индекс выделенной строки
int index = e.NewEditIndex;
GridViewRow row = GridView1.Rows[index];
//Получение старых значений полей в строке GridView
string oldGroupName = ((Label)(row.Cells[0].FindControl("myLabel1"))).Text;
//Сохранение названия группы в коллекции ViewState
ViewState["oldGroupName"] = oldGroupName;
GridView1.EditIndex = index;
GridView1.ShowFooter = false;
GridView1.DataBind();
}
//Отмена редактирования записи
protected void GridView1_RowCancelingEdit(object sender,
GridViewCancelEditEventArgs e)
{
GridView1.EditIndex = -1;
GridView1.ShowFooter = true;
GridView1.DataBind();
}
//Редактирование строки
protected void GridView1_RowUpdating(object sender,
GridViewUpdateEventArgs e)
{
int index = e.RowIndex;
GridViewRow row = GridView1.Rows[index];
string newGroupName =
((TextBox)(row.Cells[0].FindControl("myTextBox1"))).Text;
string newCuratorName =
((TextBox)(row.Cells[1].FindControl("myTextBox2"))).Text;
string newHeadmanName =
((TextBox)(row.Cells[2].FindControl("myTextBox3"))).Text;
string oldGroupName = (string)ViewState["oldGroupName"];
//Создание DAO группы
ISession hbmSession = (ISession)Session["hbmsession"];
DAOFactory factory = new NHibernateDAOFactory(hbmSession);
IGroupDAO groupDAO = factory.getGroupDAO();
//Получение группы по имени
Group group = groupDAO.getGroupByName(oldGroupName);
group.GroupName = newGroupName;
group.CuratorName = newCuratorName;
group.HeadmanName = newHeadmanName;
groupDAO.SaveOrUpdate(group);
GridView1.EditIndex = -1;
GridView1.ShowFooter = true;
GridView1.DataBind();
}
Последней функцией будет отображение списка студентов по нажатию на кнопку студенты в строке группы. По нажатию на эту кнопку должна загрузиться страница со списком студентов заданной группы. Обработчик нажатия на кнопку «Студенты» приведен ниже:
//Вывод списка всех студентов
protected void GridView1_RowCommand(object sender,
GridViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = GridView1.Rows[index];
string groupName = ((Label)(row.Cells[0].FindControl("myLabel1"))).Text;
Session["keyGroupName"] = groupName;
Response.Redirect("StudentForm.aspx");
}
}
Наш компонент GridViewподдерживает постраничное отображение данных, и событие переключения между страницами необходимо обработать, иначе данные не будут правильно отображаться. Ниже приведен код обработчика события переключения между страницами:
//Изменение номера текущей страницы
protected void GridView1_PageIndexChanging(object sender,
GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
GridView1.EditIndex = -1;
GridView1.ShowFooter = true;
GridView1.DataBind();
}
Внешний вид главной WEB-формы в запущенном виде приведен на рисунке 5.5.
Рисунок 5.5 – Внешний вид главной WEB-формы
Все функции касающиеся работы с группами успешно реализованы. Приступим к реализации функций связанных со студентами.
В первую очередь необходимо создать новую страницу – WEB-форму, как она называется вASP.NET. Чтобы создать новуюWEB-форму нажмите на проекте правой кнопкой мыши, выберите пункт меню «Добавить», затем «Создать элемент», в разделе«Web» появившегося диалога необходимо выбрать «ФормаWebForm». Введите название новойWEB-формы, напримерStudentFormи нажмите на «Добавить».
Откройте новую WEB-формуStudentFormв режиме исходного кода. Удалите весь текст, кроме первой строки, и подключите кWEB-форме шаблонUniversity. Исходный кодWEB-формыStudentFormприведен ниже:
<%@ Page Language="C#" AutoEventWireup="true"
CodeBehind="StudentForm.aspx.cs" Inherits="lab5.StudentForm"
MasterPageFile="~/University.Master"%>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1"
runat="server">
</asp:Content>
Приступим к визуальному проектированию новой WEB-формы. Откройте форму в режиме конструктора. Для разметки страницы можно использовать компонентTable. Поместите компонентTableс раздела «HTML»в редактируемой области страницыStudentForm. Оставьте у таблицы одну колонку и два рядка. В первом рядке разместите два компонентаLabel.Первуй компонент Labelбудет использоваться для отображения статического текста, а второй компонент будет использоваться для отображения названия группы. Во вторую строку таблицы поместите компонентGridView.
Полный текст StudentFormприведен ниже:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="StudentForm.aspx.cs" Inherits="lab5.StudentForm" MasterPageFile="~/University.Master"%>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1"
runat="server">
<table style="width:100%;">
<tr align="center">
<td>
<asp:Label ID="Label4" runat="server"
Text="Список студентов группы "
Font-Bold="True" Font-Size="20pt" ForeColor="Maroon">
</asp:Label>
<asp:Label ID="Label5" runat="server" Font-Bold="True"
Font-Size="20pt" ForeColor="Maroon">
</asp:Label>
</td>
</tr>
<tr>
<td>
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="false"
ShowFooter="true" ShowHeader="true"
AllowPaging="true" PageSize="10"
Font-Size="14pt" HorizontalAlign="Center"
onrowcancelingedit="GridView1_RowCancelingEdit"
onrowdeleting="GridView1_RowDeleting"
onrowediting="GridView1_RowEditing"
onrowupdating="GridView1_RowUpdating"
onpageindexchanging="GridView1_PageIndexChanging">
<Columns>
<asp:TemplateField HeaderText="Имя студента"
ItemStyle-Width="250">
<ItemTemplate>
<asp:Label id="myLabel1" runat="server"
Text='<%# Bind("FirstName")%>' />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="myTextBox1" runat="server" Width="250"
Text='<%# Bind("FirstName") %>'/>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="myFooterTextBox1" runat="server"
Width="250" Text='<%# Bind("FirstName") %>' />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Фамилия студента"
ItemStyle-Width="250">
<ItemTemplate>
<asp:Label id="myLabel2" runat="server"
Text='<%# Bind("LastName")%>' />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="myTextBox2" runat="server" Width="250"
Text='<%# Bind("LastName") %>'/>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="myFooterTextBox2" runat="server"
Width="250" Text='<%# Bind("LastName") %>' />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Пол" ItemStyle-Width="50">
<ItemTemplate>
<asp:Label id="myLabel3" runat="server"
Text='<%# Bind("Sex")%>' />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="myTextBox3" runat="server" Width="50"
Text='<%# Bind("Sex") %>'/>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="myFooterTextBox3" runat="server"
Width="50" Text='<%# Bind("Sex") %>' />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Год рождения"
ItemStyle-Width="100">
<ItemTemplate>
<asp:Label id="myLabel4" runat="server"
Text='<%# Bind("Year")%>' />
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="myTextBox4" runat="server" Width="100"
Text='<%# Bind("Year") %>'/>
</EditItemTemplate>
<FooterTemplate>
<asp:TextBox ID="myFooterTextBox4" runat="server"
Width="100" Text='<%# Bind("Year") %>' />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Команды"
ItemStyle-HorizontalAlign="Center"
FooterStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:ImageButton ID="ibEdit" runat="server"
CommandName="Edit" Text="Edit" ImageUrl="~/img/6.png"/>
<asp:ImageButton ID="ibDelete" runat="server"
CommandName="Delete" Text="Delete"
ImageUrl="~/img/3.png" />
</ItemTemplate>
<EditItemTemplate>
<asp:ImageButton ID="ibUpdate" runat="server"
CommandName="Update" Text="Update"
ImageUrl="~/img/5.png" />
<asp:ImageButton ID="ibCancel" runat="server"
CommandName="Cancel" Text="Cancel"
ImageUrl="~/img/7.png" />
</EditItemTemplate>
<FooterTemplate>
<asp:ImageButton ID="ibInsert" runat="server"
CommandName="Insert" OnClick="ibInsert_Click"
ImageUrl="~/img/2.png" />
</FooterTemplate>
</asp:TemplateField>
</Columns>
<EmptyDataTemplate>
<table border="1" cellpadding="0" cellspacing="0">
<tr>
<td width="250" align="center">
Имя студента
</td>
<td width="250" align="center">
Фамилия студента
</td>
<td width="50" align="center">
Пол
</td>
<td width="100" align="center">
Год рождения
</td>
<td>
Команды
</td>
</tr>
<tr>
<td>
<asp:TextBox ID="emptyFirstNameTextBox" runat="server"
Width="250"/>
</td>
<td>
<asp:TextBox ID="emptyLastNameTextBox" runat="server"
Width="250"/>
</td>
<td>
<asp:TextBox ID="emptySexTextBox" runat="server"
Width="50"/>
</td>
<td>
<asp:TextBox ID="emptyYearTextBox" runat="server"
Width="100"/>
</td>
<td align="center">
<asp:ImageButton ID="emptyImageButton" runat="server"
ImageUrl="~/img/2.png"
OnClick="ibInsertInEmpty_Click"/>
</td>
</tr>
</table>
</EmptyDataTemplate>
<PagerStyle HorizontalAlign ="Center" />
</asp:GridView>
</td>
</tr>
</table>
</asp:Content>
В отличие от таблицы групп, таблица студентов содержит не три колонки, а четыре, та также отсутствует кнопка для отображения списка студентов.
Далее необходимо запрограммировать функции добавления удаления, редактирования записей студентов. Откройте C# кода формы StudentForm. Как и в главной форме для начала необходимо реализовать функцию отображения студентов заданной группы в таблице. Это можно реализовать в обработчике события Page_Prerender. Текст обработчика этого события приведен ниже:
protected void Page_Prerender(object sender, EventArgs e)
{
string keyGroup = (string)Session["keyGroupName"];
Label5.Text = keyGroup;
ISession session = (ISession)Session["hbmsession"];
DAOFactory factory = new NHibernateDAOFactory(session);
IGroupDAO groupDAO = factory.getGroupDAO();
IList<Student> students = groupDAO.getAllStudentOfGroup(keyGroup);
GridView1.DataSource = students;
GridView1.DataBind();
}
Далее необходимо реализовать функцию добавления записей о студентах. Как и для таблицы групп, добавление представлено двумя обработчиками событий:
protected void ibInsert_Click(object sender, EventArgs e)
{
string keyGroup = (string)Session["keyGroupName"];
//Получаем значения полей
string s1 =
((TextBox)GridView1.FooterRow.FindControl("MyFooterTextBox1")).Text;
string s2 =
((TextBox)GridView1.FooterRow.FindControl("MyFooterTextBox2")).Text;
string s3 =
((TextBox)GridView1.FooterRow.FindControl("MyFooterTextBox3")).Text;
string s4 =
((TextBox)GridView1.FooterRow.FindControl("MyFooterTextBox4")).Text;
//Создаем сессию
ISession session = (ISession)Session["hbmsession"];
DAOFactory factory = new NHibernateDAOFactory(session);
IGroupDAO groupDAO = factory.getGroupDAO();
Group group = groupDAO.getGroupByName(keyGroup);
IStudentDAO studentDAO = factory.getStudentDAO();
//Создаем объект студента и заполняем его поля
Student student = new Student();
student.FirstName = s1;
student.LastName = s2;
student.Sex = s3[0];
student.Year = Convert.ToInt32(s4);
student.Group = group;
group.StudentList.Add(student);
//Сохраняем объект студента
studentDAO.SaveOrUpdate(student);
Response.Redirect(HttpContext.Current.Request.Url.ToString());
}
protected void ibInsertInEmpty_Click(object sender, EventArgs e)
{
string keyGroup = (string)Session["keyGroupName"];
//Получаем значения полей ввода
var parent = ((Control)sender).Parent;
var firstNameTextBox = parent
.FindControl("emptyFirstNameTextBox") as TextBox;
var lastNameTextBox = parent
.FindControl("emptyLastNameTextBox") as TextBox;
var sexTextBox = parent.FindControl("emptySexTextBox") as TextBox;
var yearTextBox = parent.FindControl("emptyYearTextBox") as TextBox;
//Создаем сессию
ISession session = (ISession)Session["hbmsession"];
DAOFactory factory = new NHibernateDAOFactory(session);
IGroupDAO groupDAO = factory.getGroupDAO();
Group group = groupDAO.getGroupByName(keyGroup);
IStudentDAO studentDAO = factory.getStudentDAO();
//Создаем объект студента и заполняем его поля
Student student = new Student();
student.FirstName = firstNameTextBox.Text;
student.LastName = lastNameTextBox.Text;
student.Sex = sexTextBox.Text[0];
student.Year = Convert.ToInt32(yearTextBox.Text);
student.Group = group;
group.StudentList.Add(student);
//Сохраняем объект студента
studentDAO.SaveOrUpdate(student);
Response.Redirect(HttpContext.Current.Request.Url.ToString());
}
Далее необходимо реализовать функцию удаления записи о студенте. Это происходит в обработчике события приведенном ниже:
//Удаление строки
protected void GridView1_RowDeleting(object sender,
GridViewDeleteEventArgs e)
{
string keyGroup = (string)Session["keyGroupName"];
//Получить индекс выделенной строки
int index = e.RowIndex;
GridViewRow row = GridView1.Rows[index];
//Получить имя студента
string firstName = ((Label)(row.Cells[0].FindControl("myLabel1"))).Text;
string lastName = ((Label)(row.Cells[1].FindControl("myLabel2"))).Text;
ISession hbmSession = (ISession)Session["hbmsession"];
DAOFactory factory = new NHibernateDAOFactory(hbmSession);
IStudentDAO studentDAO = factory.getStudentDAO();
Student student =
studentDAO.getStudentByGroupFirstNameAndLastName(keyGroup, firstName,
lastName);
//Удаление студента
if (student != null)
{
student.Group.StudentList.Remove(student);
studentDAO.Delete(student);
}
Response.Redirect(HttpContext.Current.Request.Url.ToString());
}
И последняя функция, которую необходимо реализовать, это замена студента, которая, как и в таблице группы представлена тремя обработчиками событий:
//Перевод строки в режим редактирования
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
//Получить индекс выделенной строки
int index = e.NewEditIndex;
GridViewRow row = GridView1.Rows[index];
//Получение старых значений полей в строке GridView
string oldFirstName = ((Label)(row.Cells[0].FindControl("myLabel1"))).Text;
string oldLastName = ((Label)(row.Cells[1].FindControl("myLabel2"))).Text;
//Сохранение названия группы в коллекции ViewState
ViewState["oldFirstName"] = oldFirstName;
ViewState["oldLastName"] = oldLastName;
GridView1.EditIndex = index;
GridView1.ShowFooter = false;
GridView1.DataBind();
}
//Отмена редактирования строки
protected void GridView1_RowCancelingEdit(object sender,
GridViewCancelEditEventArgs e)
{
GridView1.EditIndex = -1;
GridView1.ShowFooter = true;
GridView1.DataBind();
}
//Редактирование строки
protected void GridView1_RowUpdating(object sender,
GridViewUpdateEventArgs e)
{
string keyGroup = (string)Session["keyGroupName"];
int index = e.RowIndex;
GridViewRow row = GridView1.Rows[index];
string newFirstName =
((TextBox)(row.Cells[0].FindControl("myTextBox1"))).Text;
string newLastName =
((TextBox)(row.Cells[1].FindControl("myTextBox2"))).Text;
string newSex = ((TextBox)(row.Cells[2].FindControl("myTextBox3"))).Text;
string newYear = ((TextBox)(row.Cells[2].FindControl("myTextBox4"))).Text;
string oldFirstName = (string)ViewState["oldFirstName"];
string oldLastName = (string)ViewState["oldLastName"];
//Создание DAO группы
ISession hbmSession = (ISession)Session["hbmsession"];
DAOFactory factory = new NHibernateDAOFactory(hbmSession);
IStudentDAO studentDAO = factory.getStudentDAO();
//Получение группы по имени
Student student =
studentDAO.getStudentByGroupFirstNameAndLastName(keyGroup, oldFirstName,
oldLastName);
student.FirstName = newFirstName;
student.LastName = newLastName;
student.Sex = newSex[0];
student.Year = Convert.ToInt32(newYear);
studentDAO.SaveOrUpdate(student);
GridView1.EditIndex = -1;
GridView1.ShowFooter = true;
GridView1.DataBind();
}
Поскольку GridViewподдерживает постраничное отображение данных то необходимо обработать события перехода на следующую страницу:
protected void GridView1_PageIndexChanging(object sender,
GridViewPageEventArgs e)
{
GridView1.PageIndex = e.NewPageIndex;
GridView1.EditIndex = -1;
GridView1.ShowFooter = true;
GridView1.DataBind();
}
Форма студентов в запущенном виде представлена на рисунке 5.6.
Рисунок 5.6 – Внешний вид WEB-формы студентов