Цель практического занятия: Теперь, когда у нас имеется макет разрабатываемого сайта, необходимо реализовать различную функциональность, свойственную Интернет-магазинам. Однако для того, чтобы это сделать, одного только HTML уже не достаточно. Необходимо в рамках сайта реализовать бизнес-логику магазина. Целью данного занятия является рассмотрение основных возможностей технологии
Файлы к практическому занятию Вы можете скачать здесь.
Почти все крупномасштабные Веб-сайты
К основным преимуществам Visual Studio можно отнести следующие:
При загрузке Visual Studio 2008 отображается окно, состоящее из нескольких областей (рис. 8.1). Область окна Recent Projects содержит ссылки на 6 последних
(рис 8.1) Главное окно интегрированной среды разработки приложений Visual Studio 2008Левая и правая часть окна Visual Studio 2008 заняты так называемыми инструментальными окнами (так как набор окон и их расположение каждый разработчик настраивает так, как ему удобней, то внешний вид среды Visual Studio при запуске может сильно отличаться). В них отображаются компоненты приложений: элементы управления, соединения с базами данных, классы и свойства, используемые в
Важным компонентом интерфейса является также способ отображения окон документов внутри интегрированной среды разработки. Существует два способа отображения окон: стандартный многооконный интерфейс, используемый многими программами, когда внутри основного окна создается новое окно, которое представляет собой отдельное окно с заголовком, но которое не может быть вынесено за пределы главного окна; и интерфейс на основе закладок, когда окно документа всегда занимает все рабочее пространство внутри главного окна, а переключение между окнами возможно путем щелчка по соответствующей вкладке (рис. 8.2).
(рис 8.2) Расположение окон интегрированной среды разработки в виде вкладок
Для создания нового приложения
В открывшемся окне New Web Site (рис. 8.3) можно указать следующие сведения:
(рис 8.3) Окно создания нового Веб-приложенияПосле возврата в диалоговое окно создания Веб-сайта и указания всех необходимых опций, Visual Studio создаст новое Веб-приложение. Новый Веб-сайт начинается с одного файла – начальной страницы по умолчанию default.aspx, пример содержимого которой приведен на рис. 8.4.
(рис 8.4) Созданное новое Веб-приложениеКак видно из рисунка, основная часть файла представляет собой обычную структуру HTML-документа с той лишь разницей, что в самом начале размещена строка, содержащая директивы
Наличие расширения .aspx у файла говорит о том, что он содержит некие директивы form, исполняющегося на стороне сервера и помечаются тегом <asp: параметры элемента />. Например, описание серверного элемента Button, вставленного в страницу будет выглядеть следующим образом:
<asp:Button ID="Button1" runat="server" Text="Button" />
Как видно из этого примера, после ключевого слова asp следует тип элемента, который соответствует его классу, описанному в
Особое значение при разработке приложений играет окно панели компонентов Toolbox.
В Visual Studio окно Toolbox отображает элементы управления и компоненты, которые можно перетаскивать в окно документа. Содержимое Toolbox зависит от типа редактируемого документа. Например, при редактировании
(рис 8.5) Созданное новое Веб-приложениеФайл Default.aspx.cs содержит программный код, привязанный к странице. Организация этого файла практически полностью повторяет организацию аналогичного файла для
(рис 8.6) Элементы управления окна Toolbox в режиме редактирования исходного кодаКак видно из рисунка, файл начинается с подключения различных пространств имен, содержащих описания тех классов
Принцип разработки приложения в
Естественно, не все задачи можно решить в графическом режиме. Поэтому приходится редактировать Веб-документы в режиме исходного кода. Если хорошо знать HTML, то этот способ может оказаться даже удобнее использования графических инструментов. Поддерживаемая Visual Studio технология IntelliSense помогает завершать элементы HTML, создаваемые в режиме исходного кода.
При создании новой .vb или .cs (в зависимости от используемого языка программирования: cs соответствует языку C#, vb – Visual Basic).
В каждом файле кода Visual Studio генерирует определение класса, инициализирующие процедуры и обработчик события Page_Load.
Чтобы скрыть сгенерированный код, следует щелкнуть знак "минус" слева от директивы #Region. При этом область сворачивается, а знак "минус" меняется на "плюс", щелкнув который, область снова раскрывается. Аналогичным образом сворачивают и раскрывают и другие блоки кода, например определения классов и процедур.
Редактор кода также поддерживает функцию autocomplete, автоматически завершающую ключевые слова и члены классов, реализуемую при помощи технологии IntelliSense (рис. 8.7.). Окно подсказки появляется всякий раз, когда происходит ввод ключевого слова, представляющего собой команду, директиву, тип данных, либо зарезервированное слово. При этом пользователю достаточно выбрать из списка нужный вариант окончания данной команды и нажать клавишу Enter. В случае если окно подсказки закрылось, а команда так и не была выбрана, разработчик может вызвать его с помощью нажатия комбинации клавиш "ctrl+пробел".
(рис 8.7) Технология IntelliSense в действии при редактировании C#-кодаКроме того, после ввода каждой строки редактор кода выделяет синтаксические ошибки и необъявленные переменные, подчеркивая их волнистой линией. При наведении указателя мыши на выделенную ошибку отображается ее описание.
Visual Studio упорядочивает приложения при помощи
(рис 8.8) Окно Solution ExplorerСтартовый
Рассмотрим структуру отдельных частей созданного
После создания нового Default.aspx и Default.aspx.cs. Кроме того, автоматически создается каталог App_Data, предназначенный для хранения файлов базы данных, используемой App_Data в Default.aspx
представляет собой файл, содержащий описание Веб-страницы в формате HTML.
Таким образом, согласно такой модели организации .aspx, а исходный код размещается в файлах с расширением .cs в случае, если в качестве языка программирования используется C# и .vb – если Visual Basic.
aspx. Достаточно сложные системы часто генерируют часть элементов управления страницы в бэк-коде. При использовании подхода FrontController страницы aspx могут вообще не содержать каких-либо компонентов, а вся структура страницы будет генерироваться в методе Page_Load в зависимости от последних действий пользователя.Еще одним важным файлом
Файл Web.Config является конфигурационным файлом, созданном на базе формата XML. Фрагмент такого файла, изображен на рис. 8.9. Он содержит большое количество параметров настройки на уровне приложения, которые конфигурируют все аспекты, начиная с безопасности, и заканчивая отладкой, подключением к источникам данных и управлением состояния.
(рис 8.9) Пример файла Web.ConfigОднако, кроме перечисленных выше файлов, приложение
После того, как в Visual Studio был создан новый сайт, перейдем к переносу и адаптации кода. Прежде всего, добавим в (это можно сделать, кликнув правой клавишей мыши по названию сайт в Solution Explorer и выбрав в контекстом меню пункт Add New Item) (рис. 8.10).
(рис 8.10) Добавление MasterPage в проект Новый созданный файл заменит для нас динамические веб-шаблоны из первого занятия. В самом master.master необходимо добавить два asp -компонента типа ContentPlaceHolder, которые и будут задавать область редактирования для страниц, использующих этот master.master, который определяет две области, используемые страницами для отображения своего контента:
<div id="page_content">
<div id="column_l">
<div id="column_l_content">
<asp:ContentPlaceHolder id="column_l_placeholder" runat="server">
<h2>Headline 2</h2>
<p>insert content here</p>
</asp:ContentPlaceHolder>
</div>
</div>
<div id="column_r">
<div id="column_r_content">
<asp:ContentPlaceHolder id="column_r_placeholder" runat="server">
<h3>Headline 3</h3>
<p>insert content here</p>
</asp:ContentPlaceHolder>
</div>
</div>
</div>
MasterPage , для добавления новых пунктов меню, а также для добавления еще одного PlaceHolder 'а MasterPage 'е, необходимо при выборе пункт "Add New Item" выбирать шаблон "Web Form" и выделять условие "Select master page", так как это показано на рис. 8.11.
(рис 8.11) Добавление новых asp-страниц на сайтЕсли при разработке мастера страниц выбрать выкладку Design или Split, то отобразится страница, изображенная на рис. 8.12.
(рис 8.12) Визуализация мастера страниц в Visual Studio 2008В таком режиме легко увидеть две области редактирования, а также остальные элементы страницы, включая меню.
Для навигации по сайтам часто используется компонент ASP – Menu. Это серверный компонент управления, который позволяет создавать вертикально или горизонтально ориентированные пункты меню. Пункты меню можно задать статически на странице aspx, либо добавлять их серверным кодом, например при выполнении метода Page_Load, либо указать объекту типа Menu источник данных определенной структуры. Компонент Menu позволяет создавать многоуровневые иерархические меню, принимая на себя обязанности, по подготовке кода, отвечающего за "всплытие" разделов меню. Ниже представлен код, используемый в мастере страниц:
<div id="navigation">
<asp:Menu ID="MainMenu" runat="server" Orientation="Horizontal" >
<StaticHoverStyle CssClass="MenuItemStyle_hover"/>
<StaticMenuItemStyle CssClass="MenuItemStyle"/>
<DynamicHoverStyle CssClass="MenuItemStyle_hover"/>
<DynamicMenuItemStyle CssClass="MenuItemStyle"/>
<Items>
<asp:MenuItem NavigateUrl="~/default.aspx" Text="Главная" Value="Главная"></asp:MenuItem>
<asp:MenuItem NavigateUrl="~/products/default.aspx" Text="Продукты" Value="Продукты"></asp:MenuItem>
<asp:MenuItem NavigateUrl="~/about/default.aspx" Text="Оnbsp;компании" Value="О компании"></asp:MenuItem>
<asp:MenuItem NavigateUrl="~/contact/default.aspx" Text="Контактная информация"
Value="Контактная информация"></asp:MenuItem>
</Items>
</asp:Menu>
</div>
В теге asp:Menu задается направление отрисовки пунктов меню, в данном случае – горизонтальное. Далее указываются стили, которые надо применять к статическим и динамическим (т. е. StaticMenuItemStyle и DynamicMenuItemStyle ), а также стили этих меню, когда на них наводят мышкой ( StaticHoverStyle и DynamicHoverStyle ). Далее идет описание самих пунктов меню, основными свойствами которых являются NavigateUrl и Text. Text отвечает за отображаемое название пункта меню, а NavigateUrl – за страницу, на которую будет перенаправлен пользователь, кликнувший по этому пункту меню.
"~", что обозначается корень сайта. При рендеренге страницы, адреса в NavigateUrl будут заменены на абсолютные адреса страниц.После того, как мастер страниц разработан, можно переходить к разработке отдельных страниц.
Код главной страницы начинается с заголовка, в котором указано, что эта страница использует файл Master.master
<%@ Page Title="" Language="C#" MasterPageFile="~/Master.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
Остальная часть файла состоит из двух частей: содержимого ContentPlaceHolder 'а с ID равным column_l_placeholder и содержимого ContentPlaceHolder 'а с ID равным column_r_placeholder. Содержимое asp:Content полностью совпадает с тем, что было разработано в первом семинаре. При этом в отличие от технологии dynamic web templates при использовании не нужно дублировать один и тот же код в каждую страницу, и значит не нужно его каждый раз обновлять.
<asp:Content ID="Content1" ContentPlaceHolderID="column_l_placeholder" Runat="Server">
<h1>Добро пожаловать вnbsp;магазин велосипедов Adventure Works</h1>
<p>Adventure Works Cyclesnbsp;mdash;
вымышленная компания, наnbsp;основе которой созданы образцы баз
данных AdventureWorks,nbsp;mdash; является большой
транснациональной производственной организацией. Компания изготавливает
иnbsp;продает велосипеды изnbsp;металла иnbsp;композитных
материалов вnbsp;Северной Америке, аnbsp;также
наnbsp;европейском иnbsp;азиатском рынках. Хотя основное
производство расположено вnbsp;городе Ботель, штат Вашингтон,
иnbsp;имеет 290nbsp;служащих, существуют несколько региональных
групп продаж, расположенных наnbsp;территории рынков
сбыта.</p>
<p>Вnbsp;2000nbsp;г. Adventure Works
Cycles купила небольшой производственный завод Importadores Neptuno
вnbsp;Мексике. Предприятие Importadores Neptuno производит несколько
важных наименований комплектующих для компании Adventure Works Cycles.
Эти вспомогательные компоненты поставляются вnbsp;Ботель для
окончательной сборки продукции. Вnbsp;2001nbsp;г. Importadores
Neptuno стало единственным изготовителем иnbsp;распространителем
продуктов группы туристических велосипедов.</p>
<p>Открывая успешный финансовый год, компания
Adventure Works Cycles предполагает расширить свою долю
наnbsp;рынке, ориентируя продажи наnbsp;лучших клиентов,
расширяя доступность продукта сnbsp;помощью веб-узла
иnbsp;уменьшая себестоимость продаж заnbsp;счет снижения
издержек производства.</p>
</asp:Content>
<asp:Content ID="Content2"
ContentPlaceHolderID="column_r_placeholder"
Runat="Server">
<h3>Новинки!</h3>
<img alt="" height="149"
src="images/Black_racer02_F_large.gif"
width="240" />
<p>Travel innbsp;style and comfort.
Designed for maximum comfort and safety. Wide gear range takes
onnbsp;all hills. High-tech aluminum alloy construction provides
durability without added weight.</p>
</asp:Content>
Если запустить главную страницу, то она будет выглядеть почти также как и в первом семинаре (рис. 8.13).
(рис 8.13) Главная страница интернет магазинаАналогичным образом разрабатываются и все остальные страницы.
Отдельно стоит рассмотреть страницу продуктов, так как на ней мы покажем, каким образом в
На первом занятии, для того, чтобы отобразить список продуктов, мы использовали обычные HTML-таблицы. В общем случае, такой подход не удобен, так как данные, которые необходимо отобразить, постоянно меняются, что приводит к тому, что придется создавать разметку таблицы вручную в серверном коде (впрочем, такой подход в некоторых отдельных сложных случаях может оказаться удобен). Для того чтобы отображать и манипулировать данными, ASP предлагает несколько визуальных компонент, один из которых называется GridView. Он позволяет не только представить в удобной форме массив данных, но и предоставляет удобные механизмы для сортировки данных, выбора отдельных строк, добавления и редактирования данных.
(рис 8.14) Страница продуктов интернет-магазина, использующая GridViewНа рис. 8.14 видно, что страница продуктов похожа на ту, что было создана в первом семинаре, но сама таблица содержит дополнительный столбец с кнопками "Выбор". Рассмотрим код, который создает данную страницу:
<asp:Content ID="Content1" ContentPlaceHolderID="column_l_placeholder" Runat="Server">
<asp:GridView ID="GridViewProducts" runat="server" CellPadding="4"
GridLines="None" CssClass="GridViewProduct"
AutoGenerateColumns="False"
OnSelectedIndexChanged="OnSelectedIndexChanged" >
<RowStyle CssClass="tr_nechet" />
<AlternatingRowStyle CssClass="tr_chet" />
<Columns>
<asp:CommandField SelectText="Выбор"
ShowSelectButton="True" />
<asp:TemplateField
HeaderText="Количество наnbsp;складе"
SortExpression="StockCount" >
<ItemTemplate>
<asp:Label ID="Label1"
runat="server"
Text='<%# Eval("StockCount") %>' >
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Название" SortExpression="Name" >
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Eval("Name") %>' >
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<PagerStyle BackColor="#FFCC66"
ForeColor="#333333"
HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
<HeaderStyle CssClass="tr_main" />
</asp:GridView>
</asp:Content>
Левый ContentPlaceHolder содержит внутри себя только один компонент – GridView. Рассмотрим подробнее его определение. В корневом теге определен идентификатор документа, что позволяет работать с этим компонентом через серверный код. Там же определен CSS-класс, который будет применяться к таблице, атрибутом GridLines="None" указано, что при отрисовке таблице не надо рисовать линии между ячейками, атрибутом AutoGenerateColumns="False" указано, что набор колонок этой таблицы будет определен вручную, и самому компоненту не надо пытаться его определить на основании переданных данных.
AutoGenerateColumns присвоено значение True, то для объекта DataTable компонент создаст столбец для каждого DataColumn, определенного в коллекции Columns переданного объекта. Если же в качестве источника данных будет указан массив или список каких-либо объектов, то GridView создаст набор столбцов, соответствующих каждому публичному ( public ) свойству этих объектов.Также в корневом теге указан серверный обработчик события OnSelectedIndexChanged, которое срабатывает, когда пользователь нажимает на кнопку "Выбор" в первом столбце. В теге RowStyle определен CSS-класс, который будет применяться к каждой нечетной строке, а в теге AlternatingRowStyle – стиль, который будет применяться к каждой четной строке.
Далее определяется набор столбцов, которые будут отображаться в таблице. Компонент поддерживает несколько видов колонок, среди которых CommandField, TemplateField и BoundField (последний используется при автоматической генерации колонок, или если источник данных для таблицы заранее определен). В нашем случае, для отображения столбца, позволяющего выбирать строки, воспользуемся колонкой типа CommandField, в которой укажем, что необходимо отобразить кнопку выбора ( ShowSelectButton="True" ) и текст этой кнопки ( SelectText="Выбор" ). Этот тип столбцов используется также для определения столбцов, содержащих кнопки удаления и редактирования записей.
Далее идет определение двух колонок, которые будут отображать данные. Рассмотрим столбец, который будет отображать название продукта. Для его создания используется компонент с типом TemplateField. В корневом теге компонента указывается заголовок столбца, а также выражение, которое используется для сортировки (в этом примере – не используется). Далее определяется шаблон, который будет использоваться для отображения данных в табличке. В нашем примере используется компонент Label, который представляет собой обычную надпись, текст которой определяется атрибут Text.
Так как название каждого продукта отличается, указать в качестве текста обычную строку не получится. Для того чтобы отобразить название, воспользуемся серверным методом Eval. Метод заключен в специальную разметку <%# %>, которая в общем случае содержит любой исполняемый на сервере код. Когда к GridView привязывается определенный источник данных, то на этапе PreRender страницы у компонента вызывается метод отрисовки каждой строки (для каждой записи, которую необходимо отобразить срабатывает событие DataBinding ). Далее для каждой ячейки в строке также сработает событие DataBinding и вызывается код, написанный в <%# %>, причем в контексте текущей записи, которую необходимо отобразить. Код Eval ( "Name" ) возвратит свойство Name текущего объекта (или, если такого свойства нет, то попытается обратиться через итератор: DataItem["Name"] ), и и
менно это значение и будет отображено.
Columns компонента GridView добавить объекты типа TemplateField, у которых свойство ItemTemplate означить объект собственного класса, наследующего от ITemplate. В этом классе необходимо будет определить метод InstantiateIn, как того требует сигнатура ITemplate, в котором создать объект типа Label и положить его в коллекцию контролов контейнера следующим кодом: container.Controls.Add(label);. Далее, в этом же коде необходимо привязать обработчик события label.DataBinding и в этом обработчике определить необходимый код, например:private void label_DataBinding(object sender, EventArgs e)
{
var container = (GridDataItem) sender.NamingContainer;
((Label)sender).Value = ((CycleHelper) container.DataItem).Name;
}
Приведенный код эквивалентен тому, что мы использовали в примере, но, несмотря на то, что он намного сложнее, предоставляет намного больше возможностей, позволяя отображать в ячейках таблицы произвольные структуры данных
Подробнее об использовании методов Eval и Bind для привязки данных к различным компонентам можно почитать на сайте MSDN: http://msdn.microsoft.com/en-us/library/ms178366.aspx
Три заключительных тега – PagerStyle, SelectedRowStyle и HeaderStyle определяют внешний вид пейджера (компонента, позволяющего выводить данные постранично и выбирать текущую страницу), выбранной строки и заголовка таблицы.
Теперь, когда все готово для отображения таблицы, необходимо написать серверный код для отображения данных.
Прежде всего, определим структуру данных, которая будет использоваться для отображения. Назовем новый класс CycleHelper, и пусть он содержит два публичных свойства: StockCount и Name:
public class CycleHelper
{
public int StockCount
{
get; set;
}
public string Name
{
get; set;
}
}
Определим на самой странице типизированный список CycleHelper, который будем отображать, а в методе Page_Load заполним этот список значениями (позднее мы будем брать данные и базы данных) и привяжем методом DataBind() наш список к таблице:
List<CycleHelper> chs = new List<CycleHelper>();
protected void Page_Load(object sender, EventArgs e)
{
chs.Add(new CycleHelper() {Name = "Mountain Tire Tube",StockCount = 191});
chs.Add(new CycleHelper() {Name = "Patch Kit/8 Patches",StockCount = 184});
chs.Add(new CycleHelper() {Name = "Water Bottlenbsp;mdash; 30nbsp;oz.",StockCount = 175});
chs.Add(new CycleHelper() {Name = "Road Tire Tube",StockCount = 161});
chs.Add(new CycleHelper() {Name = "Fender Setnbsp;mdash; Mountain",StockCount = 110});
GridViewProducts.DataSource = chs;
GridViewProducts.DataBind();
}
Также добавим обработчик события OnSelectedIndexChanged компонента GridView:
protected void OnSelectedIndexChanged(object sender, EventArgs e)
{
var cycle = chs[GridViewProducts.SelectedIndex];
ProductDetails.LoadContent(cycle.Name, cycle.StockCount);
}
Чтобы этот код заработал, нам необходимо разработать собственный компонент ProductDetails.
Для разработки и повторного использования собственных компонент используются файлы с расширением ascx.
Добавим в папку products файл ProductDetails.ascx через пункт контекстного меню Add New Item (рис. 8.15).
(рис 8.15) Добавление в проект нового пользовательского серверного компонентаКак и в случае со страницей будет создано два файла, один из которых содержит разметку компонента, а второй – серверный код.
Код с разметкой начинается с заголовка, указывающего, что в этом файле описывается серверный компонент на языке C#, бэк-код которого содержится в файле ProductControl.ascx.cs, а сам компонент будет иметь название products_ProductControl:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ProductControl.ascx.cs" Inherits="products_ProductControl" %>
Остальная часть файла представляет собой обычную таблицу на HTML, которая содержит несколько компонент Label и один компонент Image. Все серверные System.Web.UI.UserControl, хотя также есть возможность унаследовать свой компонент и от некоторых других классов.
В самом компоненте определим метод Page_Load, в котором для компонента Image укажем путь к картинке (таким образом, если бы у нас была бы картинка для каждого товара, мы могли бы указать путь к этой картинке), а также установим свойство Visible значение false. Это приведет к тому, что компонент не будет отрисовываться на странице.
Также определим метод LoadContent, который будет означивать надписи компонента переданными значениями и устанавливать свойство Visble в True ;
protected void Page_Load(object sender, EventArgs e)
{
Visible = false;
Image1.ImageUrl = "~/images/Black_racer02_F_large.gif";
}
public void LoadContent(string name, int count)
{
Visible = true;
LabelName.Text = name;
LabelCount.Text = count.ToString();
}
На рис. 8.16 показано, как разработанный компонент выглядит в дизайнере Visual Studio 2008.
(рис 8.16) Отображение компонента ProductControl в дизайнере Visual Studio 2008Теперь, когда компонент разработан, добавим его на страницу products/default.aspx, в правый PlaceHolder. Для этого, добавим в начало файла следующую строчку, которая зарегистрирует компонент на странице и позволит его использовать под именем AWCDShop:ProductControl:
<%@ Register TagPrefix="AWCDShop" TagName="ProductControl" Src="~/products/ProductControl.ascx" %>
Добавим этот компонент в правый PlaceHolder:
<asp:Content ID="Content2" ContentPlaceHolderID="column_r_placeholder" Runat="Server"> <AWCDShop:ProductControl ID="ProductDetails" runat ="server" /> </asp:Content>
Далее вернемся к коду обработчика события OnSelectedIndexChanged:
var cycle = chs[GridViewProducts.SelectedIndex]; ProductDetails.LoadContent(cycle.Name, cycle.StockCount);
По умолчанию компонент не отображается на странице, однако когда пользователь выберет какую-либо строку в таблице, произойдет postback страницы, она восстановится на сервере и будет выполнен код обработчика OnSelectedIndexChanged. По свойству GridView.SelectedIndex будет определен порядковый номер продукта, и он будет извлечен из коллекции продуктов, после чего будет выполнен метод ProductDetails.LoadContent, который отобразит Label 'ы этого компонента названием и количеством продукта на складе соответственно. На рис. 8.17 показано, как будет выглядеть страница продуктов при выборе в таблице первой строки.
(рис 8.17) Отображение страницы продуктов интернет-магазина с выбранным первым продуктом
Данное практическое занятие рассматривает следующие темы:
MasterPage ;Цель практического занятия: Теперь, когда у нас имеется макет разрабатываемого сайта, необходимо реализовать различную функциональность, свойственную Интернет-магазинам. Однако для того, чтобы это сделать, одного только HTML уже не достаточно. Необходимо в рамках сайта реализовать бизнес-логику магазина. Целью данного занятия является рассмотрение основных возможностей технологии
Файлы к практическому занятию Вы можете скачать здесь.
Почти все крупномасштабные Веб-сайты
К основным преимуществам Visual Studio можно отнести следующие:
При загрузке Visual Studio 2008 отображается окно, состоящее из нескольких областей (рис. 8.1). Область окна Recent Projects содержит ссылки на 6 последних
(рис 8.1) Главное окно интегрированной среды разработки приложений Visual Studio 2008Левая и правая часть окна Visual Studio 2008 заняты так называемыми инструментальными окнами (так как набор окон и их расположение каждый разработчик настраивает так, как ему удобней, то внешний вид среды Visual Studio при запуске может сильно отличаться). В них отображаются компоненты приложений: элементы управления, соединения с базами данных, классы и свойства, используемые в
Важным компонентом интерфейса является также способ отображения окон документов внутри интегрированной среды разработки. Существует два способа отображения окон: стандартный многооконный интерфейс, используемый многими программами, когда внутри основного окна создается новое окно, которое представляет собой отдельное окно с заголовком, но которое не может быть вынесено за пределы главного окна; и интерфейс на основе закладок, когда окно документа всегда занимает все рабочее пространство внутри главного окна, а переключение между окнами возможно путем щелчка по соответствующей вкладке (рис. 8.2).
(рис 8.2) Расположение окон интегрированной среды разработки в виде вкладок
Для создания нового приложения
В открывшемся окне New Web Site (рис. 8.3) можно указать следующие сведения:
(рис 8.3) Окно создания нового Веб-приложенияПосле возврата в диалоговое окно создания Веб-сайта и указания всех необходимых опций, Visual Studio создаст новое Веб-приложение. Новый Веб-сайт начинается с одного файла – начальной страницы по умолчанию default.aspx, пример содержимого которой приведен на рис. 8.4.
(рис 8.4) Созданное новое Веб-приложениеКак видно из рисунка, основная часть файла представляет собой обычную структуру HTML-документа с той лишь разницей, что в самом начале размещена строка, содержащая директивы
Наличие расширения .aspx у файла говорит о том, что он содержит некие директивы form, исполняющегося на стороне сервера и помечаются тегом <asp: параметры элемента />. Например, описание серверного элемента Button, вставленного в страницу будет выглядеть следующим образом:
<asp:Button ID="Button1" runat="server" Text="Button" />
Как видно из этого примера, после ключевого слова asp следует тип элемента, который соответствует его классу, описанному в
Особое значение при разработке приложений играет окно панели компонентов Toolbox.
В Visual Studio окно Toolbox отображает элементы управления и компоненты, которые можно перетаскивать в окно документа. Содержимое Toolbox зависит от типа редактируемого документа. Например, при редактировании
(рис 8.5) Созданное новое Веб-приложениеФайл Default.aspx.cs содержит программный код, привязанный к странице. Организация этого файла практически полностью повторяет организацию аналогичного файла для
(рис 8.6) Элементы управления окна Toolbox в режиме редактирования исходного кодаКак видно из рисунка, файл начинается с подключения различных пространств имен, содержащих описания тех классов
Принцип разработки приложения в
Естественно, не все задачи можно решить в графическом режиме. Поэтому приходится редактировать Веб-документы в режиме исходного кода. Если хорошо знать HTML, то этот способ может оказаться даже удобнее использования графических инструментов. Поддерживаемая Visual Studio технология IntelliSense помогает завершать элементы HTML, создаваемые в режиме исходного кода.
При создании новой .vb или .cs (в зависимости от используемого языка программирования: cs соответствует языку C#, vb – Visual Basic).
В каждом файле кода Visual Studio генерирует определение класса, инициализирующие процедуры и обработчик события Page_Load.
Чтобы скрыть сгенерированный код, следует щелкнуть знак "минус" слева от директивы #Region. При этом область сворачивается, а знак "минус" меняется на "плюс", щелкнув который, область снова раскрывается. Аналогичным образом сворачивают и раскрывают и другие блоки кода, например определения классов и процедур.
Редактор кода также поддерживает функцию autocomplete, автоматически завершающую ключевые слова и члены классов, реализуемую при помощи технологии IntelliSense (рис. 8.7.). Окно подсказки появляется всякий раз, когда происходит ввод ключевого слова, представляющего собой команду, директиву, тип данных, либо зарезервированное слово. При этом пользователю достаточно выбрать из списка нужный вариант окончания данной команды и нажать клавишу Enter. В случае если окно подсказки закрылось, а команда так и не была выбрана, разработчик может вызвать его с помощью нажатия комбинации клавиш "ctrl+пробел".
(рис 8.7) Технология IntelliSense в действии при редактировании C#-кодаКроме того, после ввода каждой строки редактор кода выделяет синтаксические ошибки и необъявленные переменные, подчеркивая их волнистой линией. При наведении указателя мыши на выделенную ошибку отображается ее описание.
Visual Studio упорядочивает приложения при помощи
(рис 8.8) Окно Solution ExplorerСтартовый
Рассмотрим структуру отдельных частей созданного
После создания нового Default.aspx и Default.aspx.cs. Кроме того, автоматически создается каталог App_Data, предназначенный для хранения файлов базы данных, используемой App_Data в Default.aspx
представляет собой файл, содержащий описание Веб-страницы в формате HTML.
Таким образом, согласно такой модели организации .aspx, а исходный код размещается в файлах с расширением .cs в случае, если в качестве языка программирования используется C# и .vb – если Visual Basic.
aspx. Достаточно сложные системы часто генерируют часть элементов управления страницы в бэк-коде. При использовании подхода FrontController страницы aspx могут вообще не содержать каких-либо компонентов, а вся структура страницы будет генерироваться в методе Page_Load в зависимости от последних действий пользователя.Еще одним важным файлом
Файл Web.Config является конфигурационным файлом, созданном на базе формата XML. Фрагмент такого файла, изображен на рис. 8.9. Он содержит большое количество параметров настройки на уровне приложения, которые конфигурируют все аспекты, начиная с безопасности, и заканчивая отладкой, подключением к источникам данных и управлением состояния.
(рис 8.9) Пример файла Web.ConfigОднако, кроме перечисленных выше файлов, приложение
После того, как в Visual Studio был создан новый сайт, перейдем к переносу и адаптации кода. Прежде всего, добавим в (это можно сделать, кликнув правой клавишей мыши по названию сайт в Solution Explorer и выбрав в контекстом меню пункт Add New Item) (рис. 8.10).
(рис 8.10) Добавление MasterPage в проектНовый созданный файл заменит для нас динамические веб-шаблоны из первого занятия. В самом master.master необходимо добавить два asp -компонента типа ContentPlaceHolder, которые и будут задавать область редактирования для страниц, использующих этот master.master, который определяет две области, используемые страницами для отображения своего контента:
<div id="page_content">
<div id="column_l">
<div id="column_l_content">
<asp:ContentPlaceHolder id="column_l_placeholder" runat="server">
<h2>Headline 2</h2>
<p>insert content here</p>
</asp:ContentPlaceHolder>
</div>
</div>
<div id="column_r">
<div id="column_r_content">
<asp:ContentPlaceHolder id="column_r_placeholder" runat="server">
<h3>Headline 3</h3>
<p>insert content here</p>
</asp:ContentPlaceHolder>
</div>
</div>
</div>
MasterPage , для добавления новых пунктов меню, а также для добавления еще одного PlaceHolder 'а MasterPage 'е, необходимо при выборе пункт "Add New Item" выбирать шаблон "Web Form" и выделять условие "Select master page", так как это показано на рис. 8.11.
(рис 8.11) Добавление новых asp-страниц на сайтЕсли при разработке мастера страниц выбрать выкладку Design или Split, то отобразится страница, изображенная на рис. 8.12.
(рис 8.12) Визуализация мастера страниц в Visual Studio 2008В таком режиме легко увидеть две области редактирования, а также остальные элементы страницы, включая меню.
Для навигации по сайтам часто используется компонент ASP – Menu. Это серверный компонент управления, который позволяет создавать вертикально или горизонтально ориентированные пункты меню. Пункты меню можно задать статически на странице aspx, либо добавлять их серверным кодом, например при выполнении метода Page_Load, либо указать объекту типа Menu источник данных определенной структуры. Компонент Menu позволяет создавать многоуровневые иерархические меню, принимая на себя обязанности, по подготовке кода, отвечающего за "всплытие" разделов меню. Ниже представлен код, используемый в мастере страниц:
<div id="navigation">
<asp:Menu ID="MainMenu" runat="server" Orientation="Horizontal" >
<StaticHoverStyle CssClass="MenuItemStyle_hover"/>
<StaticMenuItemStyle CssClass="MenuItemStyle"/>
<DynamicHoverStyle CssClass="MenuItemStyle_hover"/>
<DynamicMenuItemStyle CssClass="MenuItemStyle"/>
<Items>
<asp:MenuItem NavigateUrl="~/default.aspx" Text="Главная" Value="Главная"></asp:MenuItem>
<asp:MenuItem NavigateUrl="~/products/default.aspx" Text="Продукты" Value="Продукты"></asp:MenuItem>
<asp:MenuItem NavigateUrl="~/about/default.aspx" Text="Оnbsp;компании" Value="О компании"></asp:MenuItem>
<asp:MenuItem NavigateUrl="~/contact/default.aspx" Text="Контактная информация"
Value="Контактная информация"></asp:MenuItem>
</Items>
</asp:Menu>
</div>
В теге asp:Menu задается направление отрисовки пунктов меню, в данном случае – горизонтальное. Далее указываются стили, которые надо применять к статическим и динамическим (т. е. StaticMenuItemStyle и DynamicMenuItemStyle ), а также стили этих меню, когда на них наводят мышкой ( StaticHoverStyle и DynamicHoverStyle ). Далее идет описание самих пунктов меню, основными свойствами которых являются NavigateUrl и Text. Text отвечает за отображаемое название пункта меню, а NavigateUrl – за страницу, на которую будет перенаправлен пользователь, кликнувший по этому пункту меню.
"~", что обозначается корень сайта. При рендеренге страницы, адреса в NavigateUrl будут заменены на абсолютные адреса страниц.После того, как мастер страниц разработан, можно переходить к разработке отдельных страниц.
Код главной страницы начинается с заголовка, в котором указано, что эта страница использует файл Master.master
<%@ Page Title="" Language="C#" MasterPageFile="~/Master.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
Остальная часть файла состоит из двух частей: содержимого ContentPlaceHolder 'а с ID равным column_l_placeholder и содержимого ContentPlaceHolder 'а с ID равным column_r_placeholder. Содержимое asp:Content полностью совпадает с тем, что было разработано в первом семинаре. При этом в отличие от технологии dynamic web templates при использовании не нужно дублировать один и тот же код в каждую страницу, и значит не нужно его каждый раз обновлять.
<asp:Content ID="Content1" ContentPlaceHolderID="column_l_placeholder" Runat="Server">
<h1>Добро пожаловать вnbsp;магазин велосипедов Adventure Works</h1>
<p>Adventure Works Cyclesnbsp;mdash;
вымышленная компания, наnbsp;основе которой созданы образцы баз
данных AdventureWorks,nbsp;mdash; является большой
транснациональной производственной организацией. Компания изготавливает
иnbsp;продает велосипеды изnbsp;металла иnbsp;композитных
материалов вnbsp;Северной Америке, аnbsp;также
наnbsp;европейском иnbsp;азиатском рынках. Хотя основное
производство расположено вnbsp;городе Ботель, штат Вашингтон,
иnbsp;имеет 290nbsp;служащих, существуют несколько региональных
групп продаж, расположенных наnbsp;территории рынков
сбыта.</p>
<p>Вnbsp;2000nbsp;г. Adventure Works
Cycles купила небольшой производственный завод Importadores Neptuno
вnbsp;Мексике. Предприятие Importadores Neptuno производит несколько
важных наименований комплектующих для компании Adventure Works Cycles.
Эти вспомогательные компоненты поставляются вnbsp;Ботель для
окончательной сборки продукции. Вnbsp;2001nbsp;г. Importadores
Neptuno стало единственным изготовителем иnbsp;распространителем
продуктов группы туристических велосипедов.</p>
<p>Открывая успешный финансовый год, компания
Adventure Works Cycles предполагает расширить свою долю
наnbsp;рынке, ориентируя продажи наnbsp;лучших клиентов,
расширяя доступность продукта сnbsp;помощью веб-узла
иnbsp;уменьшая себестоимость продаж заnbsp;счет снижения
издержек производства.</p>
</asp:Content>
<asp:Content ID="Content2"
ContentPlaceHolderID="column_r_placeholder"
Runat="Server">
<h3>Новинки!</h3>
<img alt="" height="149"
src="images/Black_racer02_F_large.gif"
width="240" />
<p>Travel innbsp;style and comfort.
Designed for maximum comfort and safety. Wide gear range takes
onnbsp;all hills. High-tech aluminum alloy construction provides
durability without added weight.</p>
</asp:Content>
Если запустить главную страницу, то она будет выглядеть почти также как и в первом семинаре (рис. 8.13).
(рис 8.13) Главная страница интернет магазинаАналогичным образом разрабатываются и все остальные страницы.
Отдельно стоит рассмотреть страницу продуктов, так как на ней мы покажем, каким образом в
На первом занятии, для того, чтобы отобразить список продуктов, мы использовали обычные HTML-таблицы. В общем случае, такой подход не удобен, так как данные, которые необходимо отобразить, постоянно меняются, что приводит к тому, что придется создавать разметку таблицы вручную в серверном коде (впрочем, такой подход в некоторых отдельных сложных случаях может оказаться удобен). Для того чтобы отображать и манипулировать данными, ASP предлагает несколько визуальных компонент, один из которых называется GridView. Он позволяет не только представить в удобной форме массив данных, но и предоставляет удобные механизмы для сортировки данных, выбора отдельных строк, добавления и редактирования данных.
(рис 8.14) Страница продуктов интернет-магазина, использующая GridViewНа рис. 8.14 видно, что страница продуктов похожа на ту, что было создана в первом семинаре, но сама таблица содержит дополнительный столбец с кнопками "Выбор". Рассмотрим код, который создает данную страницу:
<asp:Content ID="Content1" ContentPlaceHolderID="column_l_placeholder" Runat="Server">
<asp:GridView ID="GridViewProducts" runat="server" CellPadding="4"
GridLines="None" CssClass="GridViewProduct"
AutoGenerateColumns="False"
OnSelectedIndexChanged="OnSelectedIndexChanged" >
<RowStyle CssClass="tr_nechet" />
<AlternatingRowStyle CssClass="tr_chet" />
<Columns>
<asp:CommandField SelectText="Выбор"
ShowSelectButton="True" />
<asp:TemplateField
HeaderText="Количество наnbsp;складе"
SortExpression="StockCount" >
<ItemTemplate>
<asp:Label ID="Label1"
runat="server"
Text='<%# Eval("StockCount") %>' >
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Название" SortExpression="Name" >
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Eval("Name") %>' >
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<PagerStyle BackColor="#FFCC66"
ForeColor="#333333"
HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
<HeaderStyle CssClass="tr_main" />
</asp:GridView>
</asp:Content>
Левый ContentPlaceHolder содержит внутри себя только один компонент – GridView. Рассмотрим подробнее его определение. В корневом теге определен идентификатор документа, что позволяет работать с этим компонентом через серверный код. Там же определен CSS-класс, который будет применяться к таблице, атрибутом GridLines="None" указано, что при отрисовке таблице не надо рисовать линии между ячейками, атрибутом AutoGenerateColumns="False" указано, что набор колонок этой таблицы будет определен вручную, и самому компоненту не надо пытаться его определить на основании переданных данных.
AutoGenerateColumns присвоено значение True, то для объекта DataTable компонент создаст столбец для каждого DataColumn, определенного в коллекции Columns переданного объекта. Если же в качестве источника данных будет указан массив или список каких-либо объектов, то GridView создаст набор столбцов, соответствующих каждому публичному ( public ) свойству этих объектов.Также в корневом теге указан серверный обработчик события OnSelectedIndexChanged, которое срабатывает, когда пользователь нажимает на кнопку "Выбор" в первом столбце. В теге RowStyle определен CSS-класс, который будет применяться к каждой нечетной строке, а в теге AlternatingRowStyle – стиль, который будет применяться к каждой четной строке.
Далее определяется набор столбцов, которые будут отображаться в таблице. Компонент поддерживает несколько видов колонок, среди которых CommandField, TemplateField и BoundField (последний используется при автоматической генерации колонок, или если источник данных для таблицы заранее определен). В нашем случае, для отображения столбца, позволяющего выбирать строки, воспользуемся колонкой типа CommandField, в которой укажем, что необходимо отобразить кнопку выбора ( ShowSelectButton="True" ) и текст этой кнопки ( SelectText="Выбор" ). Этот тип столбцов используется также для определения столбцов, содержащих кнопки удаления и редактирования записей.
Далее идет определение двух колонок, которые будут отображать данные. Рассмотрим столбец, который будет отображать название продукта. Для его создания используется компонент с типом TemplateField. В корневом теге компонента указывается заголовок столбца, а также выражение, которое используется для сортировки (в этом примере – не используется). Далее определяется шаблон, который будет использоваться для отображения данных в табличке. В нашем примере используется компонент Label, который представляет собой обычную надпись, текст которой определяется атрибут Text.
Так как название каждого продукта отличается, указать в качестве текста обычную строку не получится. Для того чтобы отобразить название, воспользуемся серверным методом Eval. Метод заключен в специальную разметку <%# %>, которая в общем случае содержит любой исполняемый на сервере код. Когда к GridView привязывается определенный источник данных, то на этапе PreRender страницы у компонента вызывается метод отрисовки каждой строки (для каждой записи, которую необходимо отобразить срабатывает событие DataBinding ). Далее для каждой ячейки в строке также сработает событие DataBinding и вызывается код, написанный в <%# %>, причем в контексте текущей записи, которую необходимо отобразить. Код Eval ( "Name" ) возвратит свойство Name текущего объекта (или, если такого свойства нет, то попытается обратиться через итератор: DataItem["Name"] ), и и
менно это значение и будет отображено.
Columns компонента GridView добавить объекты типа TemplateField, у которых свойство ItemTemplate означить объект собственного класса, наследующего от ITemplate. В этом классе необходимо будет определить метод InstantiateIn, как того требует сигнатура ITemplate, в котором создать объект типа Label и положить его в коллекцию контролов контейнера следующим кодом: container.Controls.Add(label);. Далее, в этом же коде необходимо привязать обработчик события label.DataBinding и в этом обработчике определить необходимый код, например:private void label_DataBinding(object sender, EventArgs e)
{
var container = (GridDataItem) sender.NamingContainer;
((Label)sender).Value = ((CycleHelper) container.DataItem).Name;
}
Приведенный код эквивалентен тому, что мы использовали в примере, но, несмотря на то, что он намного сложнее, предоставляет намного больше возможностей, позволяя отображать в ячейках таблицы произвольные структуры данных
Подробнее об использовании методов Eval и Bind для привязки данных к различным компонентам можно почитать на сайте MSDN: http://msdn.microsoft.com/en-us/library/ms178366.aspx
Три заключительных тега – PagerStyle, SelectedRowStyle и HeaderStyle определяют внешний вид пейджера (компонента, позволяющего выводить данные постранично и выбирать текущую страницу), выбранной строки и заголовка таблицы.
Теперь, когда все готово для отображения таблицы, необходимо написать серверный код для отображения данных.
Прежде всего, определим структуру данных, которая будет использоваться для отображения. Назовем новый класс CycleHelper, и пусть он содержит два публичных свойства: StockCount и Name:
public class CycleHelper
{
public int StockCount
{
get; set;
}
public string Name
{
get; set;
}
}
Определим на самой странице типизированный список CycleHelper, который будем отображать, а в методе Page_Load заполним этот список значениями (позднее мы будем брать данные и базы данных) и привяжем методом DataBind() наш список к таблице:
List<CycleHelper> chs = new List<CycleHelper>();
protected void Page_Load(object sender, EventArgs e)
{
chs.Add(new CycleHelper() {Name = "Mountain Tire Tube",StockCount = 191});
chs.Add(new CycleHelper() {Name = "Patch Kit/8 Patches",StockCount = 184});
chs.Add(new CycleHelper() {Name = "Water Bottlenbsp;mdash; 30nbsp;oz.",StockCount = 175});
chs.Add(new CycleHelper() {Name = "Road Tire Tube",StockCount = 161});
chs.Add(new CycleHelper() {Name = "Fender Setnbsp;mdash; Mountain",StockCount = 110});
GridViewProducts.DataSource = chs;
GridViewProducts.DataBind();
}
Также добавим обработчик события OnSelectedIndexChanged компонента GridView:
protected void OnSelectedIndexChanged(object sender, EventArgs e)
{
var cycle = chs[GridViewProducts.SelectedIndex];
ProductDetails.LoadContent(cycle.Name, cycle.StockCount);
}
Чтобы этот код заработал, нам необходимо разработать собственный компонент ProductDetails.
Для разработки и повторного использования собственных компонент используются файлы с расширением ascx.
Добавим в папку products файл ProductDetails.ascx через пункт контекстного меню Add New Item (рис. 8.15).
(рис 8.15) Добавление в проект нового пользовательского серверного компонентаКак и в случае со страницей будет создано два файла, один из которых содержит разметку компонента, а второй – серверный код.
Код с разметкой начинается с заголовка, указывающего, что в этом файле описывается серверный компонент на языке C#, бэк-код которого содержится в файле ProductControl.ascx.cs, а сам компонент будет иметь название products_ProductControl:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ProductControl.ascx.cs" Inherits="products_ProductControl" %>
Остальная часть файла представляет собой обычную таблицу на HTML, которая содержит несколько компонент Label и один компонент Image. Все серверные System.Web.UI.UserControl, хотя также есть возможность унаследовать свой компонент и от некоторых других классов.
В самом компоненте определим метод Page_Load, в котором для компонента Image укажем путь к картинке (таким образом, если бы у нас была бы картинка для каждого товара, мы могли бы указать путь к этой картинке), а также установим свойство Visible значение false. Это приведет к тому, что компонент не будет отрисовываться на странице.
Также определим метод LoadContent, который будет означивать надписи компонента переданными значениями и устанавливать свойство Visble в True ;
protected void Page_Load(object sender, EventArgs e)
{
Visible = false;
Image1.ImageUrl = "~/images/Black_racer02_F_large.gif";
}
public void LoadContent(string name, int count)
{
Visible = true;
LabelName.Text = name;
LabelCount.Text = count.ToString();
}
На рис. 8.16 показано, как разработанный компонент выглядит в дизайнере Visual Studio 2008.
(рис 8.16) Отображение компонента ProductControl в дизайнере Visual Studio 2008Теперь, когда компонент разработан, добавим его на страницу products/default.aspx, в правый PlaceHolder. Для этого, добавим в начало файла следующую строчку, которая зарегистрирует компонент на странице и позволит его использовать под именем AWCDShop:ProductControl:
<%@ Register TagPrefix="AWCDShop" TagName="ProductControl" Src="~/products/ProductControl.ascx" %>
Добавим этот компонент в правый PlaceHolder:
<asp:Content ID="Content2" ContentPlaceHolderID="column_r_placeholder" Runat="Server"> <AWCDShop:ProductControl ID="ProductDetails" runat ="server" /> </asp:Content>
Далее вернемся к коду обработчика события OnSelectedIndexChanged:
var cycle = chs[GridViewProducts.SelectedIndex]; ProductDetails.LoadContent(cycle.Name, cycle.StockCount);
По умолчанию компонент не отображается на странице, однако когда пользователь выберет какую-либо строку в таблице, произойдет postback страницы, она восстановится на сервере и будет выполнен код обработчика OnSelectedIndexChanged. По свойству GridView.SelectedIndex будет определен порядковый номер продукта, и он будет извлечен из коллекции продуктов, после чего будет выполнен метод ProductDetails.LoadContent, который отобразит Label 'ы этого компонента названием и количеством продукта на складе соответственно. На рис. 8.17 показано, как будет выглядеть страница продуктов при выборе в таблице первой строки.
(рис 8.17) Отображение страницы продуктов интернет-магазина с выбранным первым продуктом
Данное практическое занятие рассматривает следующие темы:
MasterPage ;Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.