Взаимодействие со страницей содержимого на эталонной странице (VB)

Скотт Митчелл

Проверяет, как вызывать методы, задавать свойства и т. д. страницы содержимого из кода главной страницы.

Введение

В предыдущем руководстве было рассмотрено, как программно взаимодействовать страницы содержимого со страницей master. Напомним, что мы обновили страницу master, добавив элемент управления GridView, в который перечислены пять последних добавленных продуктов. Затем мы создали страницу содержимого, с которой пользователь может добавить новый продукт. При добавлении нового продукта страница содержимого должна была указать странице master обновить gridView, чтобы она включала только что добавленный продукт. Эта функция была реализована путем добавления открытого метода на страницу master, которая обновила данные, привязанные к GridView, и последующего вызова этого метода со страницы содержимого.

Наиболее распространенная форма содержимого и master взаимодействия со страницей происходит из страницы содержимого. Однако страница master может привести текущую страницу содержимого в действие, и такая функциональность может потребоваться, если страница master содержит элементы пользовательского интерфейса, позволяющие пользователям изменять данные, которые также отображаются на странице содержимого. Рассмотрим страницу содержимого, отображающую сведения о продуктах в элементе управления GridView, и страницу master, содержащую элемент управления Кнопка, который при щелчке удваивает цены на все продукты. Как и в примере из предыдущего руководства, gridView необходимо обновить после нажатия кнопки двойной цены, чтобы отобразить новые цены, но в этом сценарии это страница master, которая должна превратить страницу содержимого в действие.

В этом руководстве описывается, как определить функциональность вызова страницы master на странице содержимого.

Создание программного взаимодействия с помощью обработчиков событий и событий

Вызвать функцию страницы содержимого из master страницы сложнее, чем наоборот. Так как страница контента имеет одну master страницу, при запуске программного взаимодействия со страницы содержимого мы знаем, какие открытые методы и свойства находятся в нашем распоряжении. Однако страница master может содержать множество разных страниц содержимого, каждая из которых имеет собственный набор свойств и методов. Как же написать код на странице master, чтобы выполнить какое-либо действие на странице содержимого, если неизвестно, какая страница содержимого будет вызываться до выполнения?

Рассмотрим веб-элемент управления ASP.NET, например элемент управления Кнопка. Элемент управления Кнопка может отображаться на любом количестве ASP.NET страниц и нуждается в механизме, с помощью которого он может оповещать страницу о том, что она была нажата. Для этого используются события . В частности, элемент управления Кнопка вызывает событие Click при щелчке; страница ASP.NET, содержащая кнопку, может при необходимости реагировать на это уведомление с помощью обработчика событий.

Этот же шаблон можно использовать для активации master страницы на страницах содержимого:

  1. Добавьте событие на страницу master.
  2. Вызывает событие всякий раз, когда страница master должна взаимодействовать со своей страницей содержимого. Например, если страница master должна предупредить свою страницу содержимого о том, что пользователь удвоил цены, ее событие будет повышено сразу после удвоить цены.
  3. Создайте обработчик событий на страницах содержимого, которые должны предпринять определенные действия.

В оставшейся части этого руководства реализован пример, описанный во введении. а именно: страница содержимого со списком продуктов в базе данных и страница master, которая содержит элемент управления Кнопка для удвоить цены.

Шаг 1. Отображение продуктов на странице содержимого

Первым делом мы создадим страницу содержимого, на которую перечислены продукты из базы данных Northwind. (Мы добавили базу данных Northwind в проект в предыдущем руководстве Взаимодействие с главной страницей со страницы содержимого.) Начните с добавления новой страницы ASP.NET в ~/Admin папку с именем Products.aspx, обязательно привязав ее к Site.master странице master. На рисунке 1 показана Обозреватель решений после добавления этой страницы на веб-сайт.

Добавление новой страницы ASP.NET в папку Администратор

Рис. 01. Добавление новой страницы ASP.NET в папку Admin (щелкните для просмотра полноразмерного изображения)

Напомним, что в учебнике Указание заголовка, метатегов и других заголовков HTML в главной странице мы создали пользовательский класс базовой страницы с именем BasePage , который создает заголовок страницы, если он не задан явным образом. Перейдите к классу Products.aspx кода программной части страницы и наследуйте его от BasePage (а не от System.Web.UI.Page).

Наконец, обновите файл, Web.sitemap включив запись для этого урока. Добавьте следующую разметку под для <siteMapNode> урока Взаимодействие содержимого с главной страницей:

<siteMapNode url="~/Admin/Products.aspx" title="Master to Content Page Interaction" />

Добавление этого <siteMapNode> элемента отражено в списке Уроки (см. рис. 5).

Вернитесь к Products.aspx. В элементе управления Содержимое для MainContentдобавьте элемент управления GridView и назовите его ProductsGrid. Привяжите GridView к новому элементу управления SqlDataSource с именем ProductsDataSource.

Привязка GridView к новому элементу управления SqlDataSource

Рис. 02. Привязка GridView к новому элементу управления SqlDataSource (щелкните для просмотра полноразмерного изображения)

Настройте мастер таким образом, чтобы он использовал базу данных Northwind. Если вы работали с предыдущим руководством, у вас уже должен быть строка подключения с именем NorthwindConnectionString в Web.config. Выберите этот строка подключения в раскрывающемся списке, как показано на рисунке 3.

Настройка SqlDataSource для использования базы данных Northwind

Рис. 03. Настройка SqlDataSource для использования базы данных Northwind (щелкните, чтобы просмотреть полноразмерное изображение)

Затем укажите оператор элемента управления SELECT источником данных, выбрав таблицу Products из раскрывающегося списка и возвратив ProductName столбцы и UnitPrice (см. рис. 4). Нажмите кнопку Далее, а затем — Готово, чтобы завершить работу мастера настройки источника данных.

Возврат полей ProductName и UnitPrice из таблицы Products

Рис. 04. Возврат ProductName полей и UnitPrice из Products таблицы (щелкните для просмотра полноразмерного изображения)

Вот и все! После завершения работы мастера Visual Studio добавляет два BoundField в GridView для зеркало двух полей, возвращаемых элементом управления SqlDataSource. Ниже приведена разметка элементов управления GridView и SqlDataSource. На рисунке 5 показаны результаты при просмотре в браузере.

<asp:GridView ID="ProductsGrid" runat="server" AutoGenerateColumns="False" 
 DataSourceID="ProductsDataSource">
 <Columns>
 <asp:BoundField DataField="ProductName" HeaderText="ProductName" 
 SortExpression="ProductName" />
 <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" 
 SortExpression="UnitPrice" />
 </Columns>
</asp:GridView>

<asp:SqlDataSource ID="ProductsDataSource" runat="server" 
 ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
 SelectCommand="SELECT [ProductName], [UnitPrice] FROM [Products]">
</asp:SqlDataSource>

Каждый продукт и его цена перечислены в GridView

Рис. 05. Каждый продукт и его цена перечислены в GridView (щелкните, чтобы просмотреть полноразмерное изображение)

Примечание

Вы можете очистить внешний вид GridView. Некоторые рекомендации включают форматирование отображаемого значения UnitPrice в качестве валюты и использование цветов фона и шрифтов для улучшения внешнего вида сетки. Дополнительные сведения о отображении и форматировании данных в ASP.NET см. в серии руководств по работе с данными.

Шаг 2. Добавление кнопки "Двойные цены" на главную страницу

Наша следующая задача — добавить веб-элемент управления Button на страницу master, которая при щелчке удвоит цену всех продуктов в базе данных. Откройте страницу Site.master master и перетащите элемент Button с панели элементов на Designer, поместив его под RecentProductsDataSource элементом управления SqlDataSource, добавленным в предыдущем руководстве. Задайте для свойства Кнопки ID значение DoublePrice , а для свойства Text — значение "Двойные цены на продукты".

Затем добавьте элемент управления SqlDataSource на страницу master, назвав его DoublePricesDataSource. Этот sqlDataSource будет использоваться для выполнения инструкции UPDATE для удвоить все цены. В частности, необходимо задать для свойств ConnectionString и UpdateCommand соответствующие строка подключения и UPDATE оператору . Затем необходимо вызвать метод этого элемента управления Update SqlDataSource при нажатии кнопки DoublePrice . Чтобы задать ConnectionString свойства и UpdateCommand , выберите элемент управления SqlDataSource и перейдите к окно свойств. В свойстве ConnectionString перечислены строки подключения, уже хранящиеся в Web.config раскрывающемся списке; выберите параметр, как показано на NorthwindConnectionString рисунке 6.

Настройка SqlDataSource для использования NorthwindConnectionString

Рис. 06. Настройка SqlDataSource для использования NorthwindConnectionString (щелкните для просмотра полноразмерного изображения)

Чтобы задать UpdateCommand свойство , найдите параметр UpdateQuery в окно свойств. При выборе этого свойства отображается кнопка с многоточием; Нажмите эту кнопку, чтобы отобразить диалоговое окно Редактор команды и параметра, показанное на рис. 7. В текстовое поле диалогового окна введите следующую UPDATE инструкцию:

UPDATE Products SET UnitPrice = UnitPrice * 2

Эта инструкция при выполнении удвоит значение для каждой UnitPrice записи в Products таблице.

Установка свойства UpdateCommand в SqlDataSource

Рис. 07. Установка свойства SqlDataSource UpdateCommand (щелкните для просмотра полноразмерного изображения)

После установки этих свойств декларативная разметка элементов управления Button и SqlDataSource должна выглядеть примерно так:

<asp:Button ID="DoublePrice" runat="server" 
 Text="Double Product Prices" />

<asp:SqlDataSource ID="DoublePricesDataSource" runat="server" 
 UpdateCommand="UPDATE Products SET UnitPrice = UnitPrice * 2" 
 ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
 ProviderName="<%$ ConnectionStrings:NorthwindConnectionString.ProviderName %>">
</asp:SqlDataSource>

Остается только вызвать его Update метод при нажатии кнопки DoublePrice . Создайте Click обработчик событий для DoublePrice Button и добавьте следующий код:

Protected Sub DoublePrice_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles DoublePrice.Click
 ' Double the prices
 DoublePricesDataSource.Update()
End Sub

Чтобы протестировать эту функцию, перейдите на страницу ~/Admin/Products.aspx , созданную на шаге 1, и нажмите кнопку "Удвоить цены на продукты". Нажатие кнопки вызывает обратную передачу DoublePrice и выполняет обработчик событий Button Click , удвояя цены на все продукты. Затем страница повторно отрисовывается, а разметка возвращается и отображается в браузере. Однако gridView на странице содержимого содержит те же цены, что и до нажатия кнопки "Двойные цены на продукты". Это связано с тем, что данные, изначально загруженные в GridView, хранились в состоянии представления, поэтому они не перезагружаются при обратной отправке, если не указано иное. Если вы перейдете на другую страницу, а затем вернетесь на нее ~/Admin/Products.aspx , вы увидите обновленные цены.

Шаг 3. Создание события при удволении цен

Так как Элемент GridView на ~/Admin/Products.aspx странице не сразу отражает удвоение цены, пользователь может понять, что он не нажимал кнопку "Двойные цены на продукты" или что она не сработала. Они могут попытаться нажать кнопку еще несколько раз, удвоив цены снова и снова. Чтобы устранить эту проблему, необходимо, чтобы в сетке на странице содержимого отображались новые цены сразу после их удвоить.

Как обсуждалось ранее в этом руководстве, необходимо вызывать событие на странице master каждый раз, когда пользователь нажимает кнопкуDoublePrice. Событие — это способ для одного класса (издателя событий) уведомлять другого набора других классов (подписчиков событий) о том, что произошло что-то интересное. В этом примере master страница является издателем событий; страницы содержимого, которые интересуются нажатием DoublePrice кнопки, являются подписчиками.

Класс подписывается на событие путем создания обработчика событий, который является методом, который выполняется в ответ на возникающее событие. Издатель определяет события, которые он вызывает, определяя делегат события. Делегат события указывает, какие входные параметры должен принимать обработчик событий. В платформа .NET Framework делегаты событий не возвращают значения и принимают два входных параметра:

  • , Objectопределяющий источник события, и
  • Класс, производный от System.EventArgs

Второй параметр, передаваемый обработчику событий, может содержать дополнительные сведения о событии. Хотя базовый EventArgs класс не передает никаких сведений, платформа .NET Framework включает ряд классов, которые расширяют EventArgs и охватывают дополнительные свойства. Например, CommandEventArgs экземпляр передается обработчикам событий, которые реагируют на Command событие, и включает два информационных свойства: CommandArgument и CommandName.

Примечание

Дополнительные сведения о создании, вызове и обработке событий см. в разделах События и Делегаты и Делегаты событий на простом английском языке.

Чтобы определить событие, используйте следующий синтаксис:

Public Event eventName As eventDelegate

Так как нам нужно оповещать страницу содержимого только тогда, когда пользователь нажал кнопку DoublePrice и не нужно передавать другие дополнительные сведения, мы можем использовать делегат EventHandlerсобытия , который определяет обработчик событий, который принимает в качестве второго параметра объект типа System.EventArgs. Чтобы создать событие на странице master, добавьте следующую строку кода в класс кода программной части страницы master:

Partial Class Site
 Inherits System.Web.UI.MasterPage

 Public Event PricesDoubled As EventHandler
 ...
End Class

Приведенный выше код добавляет общедоступное событие на страницу master с именем PricesDoubled. Теперь нам нужно поднять это событие после того, как цены были удвоены. Чтобы вызвать событие, используйте следующий синтаксис:

RaiseEvent eventName(sender, eventArgs)

Отправитель и eventArgs — это значения, которые необходимо передать обработчику событий подписчика.

Обновите DoublePriceClick обработчик событий следующим кодом:

Protected Sub DoublePrice_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles DoublePrice.Click
 ' Double the prices
 DoublePricesDataSource.Update()

 ' Refresh RecentProducts
 RecentProducts.DataBind()

 ' Raise the PricesDoubled event
 RaiseEvent PricesDoubled(Me, EventArgs.Empty)
End Sub

Как и раньше, Click обработчик событий начинается с вызова DoublePricesDataSource метода элемента управления Update SqlDataSource, чтобы удвоить цены на все продукты. После этого есть два дополнения к обработчику событий. RecentProducts Сначала обновляются данные GridView. Этот элемент GridView был добавлен на страницу master в предыдущем руководстве и отображает пять последних добавленных продуктов. Нам нужно обновить эту сетку, чтобы она отображала только что удвоив цены на эти пять продуктов. После этого PricesDoubled возникает событие . Ссылка на саму страницу master (Me) отправляется обработчику событий в качестве источника события, а пустой EventArgs объект отправляется в качестве аргументов события.

Шаг 4. Обработка события на странице содержимого

На этом этапе страница master вызывает событие PricesDoubled при каждом щелчке DoublePrice элемента управления Кнопка. Тем не менее, это только половина дела - нам все еще нужно обрабатывать событие в подписчике. Это включает два шага: создание обработчика событий и добавление кода подключения событий, чтобы при возникновении события выполнялся обработчик событий.

Начните с создания обработчика событий с именем Master_PricesDoubled. Из-за того, как мы определили PricesDoubled событие на странице master, два входных параметра обработчика событий должны иметь типы Object и EventArgsсоответственно. В обработчике событий вызовите ProductsGrid метод GridView DataBind , чтобы повторно привязать данные к сетке.

Private Sub Master_PricesDoubled(ByVal sender As Object, ByVal e As EventArgs)
 ' Rebind data to ProductsGrid
 ProductsGrid.DataBind()
End Sub

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

AddHandler publisher.eventName, AddressOf methodName

publisher — это ссылка на объект, который предлагает eventName, а methodName — это имя обработчика событий, определенного в подписчике.

Этот код подключения к событиям должен выполняться при первом посещении страницы и последующих обратных передач и должен происходить в точке жизненного цикла страницы, предшествующей возникновению события. Хорошее время для добавления кода подключения событий находится на этапе PreInit, который происходит очень рано в жизненном цикле страницы.

Откройте ~/Admin/Products.aspx и создайте Page_PreInit обработчик событий:

Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs) Handles Me.PreInit
 ' TODO: Put event wiring logic here
End Sub

Чтобы завершить этот код подключения, нам потребуется программная ссылка на страницу master со страницы содержимого. Как отмечалось в предыдущем руководстве, это можно сделать двумя способами.

  • Путем приведения свойства слабого типа Page.Master к соответствующему типу страницы master, или
  • Путем @MasterType добавления директивы на страницу .aspx и последующего использования строго типизированного Master свойства.

Давайте воспользуемся последним подходом. Добавьте следующую @MasterType директиву в начало декларативной разметки страницы:

<%@ MasterType VirtualPath="~/Site.master" %>

Затем добавьте следующий код подключения событий в Page_PreInit обработчик событий:

Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs) Handles Me.PreInit
 AddHandler Master.PricesDoubled, AddressOf Master_PricesDoubled
End Sub

С помощью этого кода Элемент GridView на странице содержимого обновляется при каждом нажатии кнопки DoublePrice .

Это поведение показано на рисунках 8 и 9. На рисунке 8 показана страница при первом посещении. Обратите внимание, что значения цен в RecentProducts GridView (в левом столбце страницы master) и ProductsGrid GridView (на странице содержимого). На рисунке 9 показан тот же экран сразу после DoublePrice нажатия кнопки. Как видите, новые цены мгновенно отражаются в обоих элементах GridView.

Значения начальной цены

Рис. 08. Начальные значения цен (щелкните для просмотра полноразмерного изображения)

Цены Just-Doubled отображаются в GridViews

Рис. 09. Цены на Just-Doubled отображаются в GridViews (Щелкните для просмотра полноразмерного изображения)

Сводка

В идеале страница master и страницы ее содержимого полностью отделены друг от друга и не требуют никакого уровня взаимодействия. Однако если у вас есть страница master или страница содержимого, на которых отображаются данные, которые можно изменить с master страницы или страницы содержимого, может потребоваться, чтобы страница master оповещала страницу содержимого (или наоборот) при изменении данных, чтобы можно было обновить отображение. В предыдущем руководстве мы узнали, как страница содержимого программно взаимодействовать со своей master страницей. В этом руководстве мы рассмотрели, как инициировать взаимодействие с master страницы.

Хотя программное взаимодействие между содержимым и master страницей может происходить из содержимого или master страницы, используемый шаблон взаимодействия зависит от источника. Различия связаны с тем, что страница содержимого имеет одну страницу master, но на master странице может быть много разных страниц содержимого. Вместо того, чтобы master страница напрямую взаимодействовала со страницей содержимого, лучше настроить master страницу для вызова события, чтобы сообщить о выполнении какого-либо действия. Те страницы содержимого, которые заботятся о действии, могут создавать обработчики событий.

Счастливого программирования!

Дополнительные материалы

Дополнительные сведения о темах, рассмотренных в этом руководстве, см. в следующих ресурсах:

Об авторе

Скотт Митчелл(Scott Mitchell), автор нескольких книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с веб-технологиями Майкрософт с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Sams Teach Yourself ASP.NET 3,5 в 24 часа. Скотт может быть доступен в mitchell@4GuysFromRolla.com или через его блог по адресу http://ScottOnWriting.NET.

Особая благодарность

Эта серия учебников была рассмотрена многими полезными рецензентами. Ведущим рецензентом этого руководства был Сухи Банерджи. Хотите просмотреть предстоящие статьи MSDN? Если да, бросить мне строку на mitchell@4GuysFromRolla.com