Главная страница Случайная страница Разделы сайта АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
💸 Как сделать бизнес проще, а карман толще?
Тот, кто работает в сфере услуг, знает — без ведения записи клиентов никуда. Мало того, что нужно видеть свое раписание, но и напоминать клиентам о визитах тоже.
Проблема в том, что средняя цена по рынку за такой сервис — 800 руб/мес или почти 15 000 руб за год. И это минимальный функционал.
Нашли самый бюджетный и оптимальный вариант: сервис VisitTime.⚡️ Для новых пользователей первый месяц бесплатно. А далее 290 руб/мес, это в 3 раза дешевле аналогов. За эту цену доступен весь функционал: напоминание о визитах, чаевые, предоплаты, общение с клиентами, переносы записей и так далее. ✅ Уйма гибких настроек, которые помогут вам зарабатывать больше и забыть про чувство «что-то мне нужно было сделать». Сомневаетесь? нажмите на текст, запустите чат-бота и убедитесь во всем сами! Порядок выполнения работы. В данном порядке выполнения лабораторной работы будет описано создание WEB-приложения, в функции которого входит отображение
В данном порядке выполнения лабораторной работы будет описано создание WEB-приложения, в функции которого входит отображение, добавление, удаление и редактирование групп, отображение, добавление, удаление и редактирование студентов в группе. В качестве источника данных, как и в предыдущей лабораторной работе, будет использоваться СУБД PostgreSQL и созданный в ппредыдущей лабораторной работе слой доступа к данным. 1. Создайте новый проект Веб-приложение ASP.NET (нажмите «Файл», «Создать», «Проект», в появившемся окне выберите «Web», «Веб-приложение ASP.NET», задайте каталог проекта и имя проекта, например lab5). 2. Добавьте в каталог с проектом библиотеки для работы с СУБД PostgreSQL, библиотеки NHibernate и библиотеки Fluent NHibernate. Данные библиотеки можно скачать по ссылкам:
В данном проекте были использованы архивы: - Npgsql2.0.10-bin-ms.net.zip - NHibernate-2.1.2.GA-bin.zip - fluentnhibernate-1.1.zip Список всех необходимых библиотек приведен ниже:
Подключите библиотеки Npgsql.dll, NHibernate.dll, FluentNHibernate.dll и NHibernate.ByteCode.Castle к проекту (нажмите правой кнопкой на «Ссылки» в дереве объектов потом на «Добавить ссылку…», перейдите на закладку «Обзор», выберите необходимые файлы). 3. Добавьте в проекте каталоги dao, domain, img, mapping. Каталоги dao, domain, mapping будут использоваться для хранения классов слоя доступа к данным DAO, реализованного в предыдущей лабораторной работе, а каталог img будет использоваться для хранения изображений приложения. Каталоги dao, domain, img, mapping в обозревателе решений изображены на рисунке 5.1. Рисунок 5.1 – Каталоги dao, domain, img, mapping в обозревателе решений 4. Скопируйте классы слоя доступа к данным, созданные в предыдущей лабораторной работке в соответствующие каталоги WEB-приложения. Это можно сделать, например, с использованием файлового менеджера Total Commander. Откройте каталог dao с предыдущей лабораторной работы и скопируйте все классы в каталог dao проекта WEB-приложения. Результаты копирования представлены на рисунке 5.2. Рисунок 5.2 – Результаты копирования классов с каталога dao предыдущего проекта в каталог dao WEB-приложения Классы каталогов domain и mapping таким же образом необходимо скопировать в соответствующие каталоги WEB-приложения. После копирования классов в проекте они не появятся, поэтому их следует добавить в проект (нажмите правой кнопкой мыши на каталог dao и в контекстном меню выберете пункт «Добавить», «Существующий элемент», в открывшемся диалоге выберете все классы каталога dao WEB-приложения и нажмите «Добавить»). Те же действия произведите с классами каталогов domain и mapping. В проекте должны появиться все классы слоя доступа к данным. Результат представлен на рисунке 5.3. Рисунок 5.3 – Результат добавления классов слоя доступа к данным Таким образом, все классы слоя доступа к данным были перенесены в WEB-приложение, и их можно использовать для отображения, добавления, удаления, замены данных. 5. Приступим к реализации интерфейса нашего WEB-приложения. Он у нас будет состоять из двух страниц. На одной странице будет отображаться список групп, а по нажатию на группу на второй будет отображаться список студентов группы. Эти страницы будут однотипными, у каждой из них будет шапка с названием страницы, футер (нижняя часть страницы) и меню. В данном случае страниц всего две, но в реальных проектах их может быть намного больше и те части, которые являются для группы страниц однотипными лучше выносить в шаблон страницы. 6. Создадим шаблон страницы для WEB-приложения. Нажмите правой кнопкой мыши на проект, нажмите «Добавить», затем «Создать элемент», в появившемся диалоге выберете «Web», затем «Главная страница», введите имя шаблона страницы, например University и нажмите «Добавить». 7. Откройте шаблон страницы University с помощью редактора главных страниц (нажмите правой кнопкой на шаблон страницы University, выберете «Открыть с помощью», в открывшемся диалоге выберете «Редактор главных страниц (По умолчанию)»). Откроется код шаблона главной страницы, который обычно состоит из html тегов и из тегов ASP.NET. Шаблон главной страницы можно редактировать как в текстовом, так и графическом режиме, перетаскивая необходимые элементы с палитры компонентов, html-теги чаще всего используются для разметки страницы. Неотъемлемым тегом шаблона страницы является тег:
< asp: ContentPlaceHolder ID=" ContentPlaceHolder1" runat=" server" > < /asp: ContentPlaceHolder>
Вместо этого тега на страницах, которые наследуют шаблон страницы, подставляется необходимое содержимое. Спроектируем шаблон страницы в графическом режиме. 8. Откройте шаблон страницы University с использованием графического редактора (нажмите два раза на шаблон страницы и из трех возможных вариантов «Конструктор», «Разделить», «Исходный код» выберите «Конструктор»). Для разметки страницы будем использовать таблицы. 9. Откройте палитру компонентов, разместите в верхней части шаблона страницы три компонент Table с раздела HTML. Один компонент будет использоваться для размещения header (верхней части страницы), второй компонент будет использоваться для размещения основной части страницы, а третий будет использоваться для размещения footer(нижней части страницы). Таблицы по умолчанию создаются с тремя рядками и тремя колонками и их необходимо настроить соответствующим образом. 10. Настроим 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>
Как видно из текста таблицы, для первой колони, устанавливается ширина по размеру изображения, а для второй колонки устанавливается цвет заливки и выравнивание по центру. 11. Приступим к реализации центральной части страницы, представленной центральной таблицей. Центральная таблица также должна состоять из одной строчки и двух колонок. В левой колонке будет размещаться меню приложения, но оно в данном примере использоваться не будет, поскольку приложение состоит всего лишь с двух страниц, поэтому мы только расположим меню в левой колонке, заполним названия пунктов меню, а адреса страниц, на которые необходимо переходить при нажатии на пункты меню заполнять не будем. Как удалять лишние колонки и строки, показано в предыдущем пункте данного руководства. Разместите в левой колонке компонент 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, в нижній располагается самом меню. 12. Приступим к реализации нижней части страницы, представленной нижней таблицей. Она будет состоять с двух строк и одной колонки. В первой строке будет размещаться линия разделения футера от основной части страницы, а во второй строке будет размещаться футер страницы. Текст нижней таблицы приведен ниже:
< 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" " https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns=" https://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 – Внешний вид шаблона страницы 13. Шаблон страницы удобно использовать для инициализации сессии 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. Наш шаблон готов и теперь мы можем использовать его для оформления наших страниц. 14. Приступим к реализации главной страницы, на которой будет располагаться список групп. Необходимо будет реализовать такие функции как добавление, удаление замена данных о группах, а также отображение списка студентов группы. Страница 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> на странице быть не должно. Если страница использует шаблон страницы, во все эти теги уже присутствуют в шаблоне. 15. Переходим к визуальному проектированию страницы 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. 16. Откройте C# код страницы Default.aspx. Поскольку все функции нашего приложения, которые нам необходимо запрограммировать будут использовать сессию NHibernate, то в первую получить сессию NHibernate c объекта 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. 17. Далее необходимо реализовать функцию добавления группы. Поскольку компонент 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()); }
18. Далее необходимо реализовать функцию удаления группы. Удаление группы происходит по событию 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()); }
19. Далее необходимо реализовать функцию редактирования записи. Строка компонента 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(); }
20. Последней функцией будет отображение списка студентов по нажатию на кнопку студенты в строке группы. По нажатию на эту кнопку должна загрузиться страница со списком студентов заданной группы. Обработчик нажатия на кнопку «Студенты» приведен ниже:
//Вывод списка всех студентов 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"); } }
21. Наш компонент 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-формы Все функции касающиеся работы с группами успешно реализованы. Приступим к реализации функций связанных со студентами. 22. В первую очередь необходимо создать новую страницу – WEB-форму, как она называется в ASP.NET. Чтобы создать новую WEB-форму нажмите на проекте правой кнопкой мыши, выберите пункт меню «Добавить», затем «Создать элемент», в разделе «Web» появившегося диалога необходимо выбрать «Форма Web Form». Введите название новой WEB-формы, например StudentForm и нажмите на «Добавить». 23. Откройте новую 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>
24. Приступим к визуальному проектированию новой 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>
В отличие от таблицы групп, таблица студентов содержит не три колонки, а четыре, та также отсутствует кнопка для отображения списка студентов. 25. Далее необходимо запрограммировать функции добавления удаления, редактирования записей студентов. Откройте 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(); }
26. Далее необходимо реализовать функцию добавления записей о студентах. Как и для таблицы групп, добавление представлено двумя обработчиками событий:
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()); }
27. Далее необходимо реализовать функцию удаления записи о студенте. Это происходит в обработчике события приведенном ниже:
//Удаление строки 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()); }
28. И последняя функция, которую необходимо реализовать, это замена студента, которая, как и в таблице группы представлена тремя обработчиками событий:
//Перевод строки в режим редактирования 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(); }
29. Поскольку 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-формы студентов
|