Взаимодействие со страницей содержимого на эталонной странице (C#)
Проверяет, как вызывать методы, задавать свойства и т. д. страницы содержимого из кода на главной странице.
Введение
В предыдущем руководстве было рассмотрено, как программно взаимодействовать страницы содержимого со своей master страницей. Напомним, что мы обновили страницу master, добавив элемент управления GridView со списком пяти последних добавленных продуктов. Затем мы создали страницу содержимого, с которой пользователь может добавить новый продукт. При добавлении нового продукта страница содержимого должна была указать странице master обновить gridView, чтобы она включала только что добавленный продукт. Эта функция была реализована путем добавления открытого метода на страницу master, которая обновила данные, привязанные к GridView, а затем вызвала этот метод со страницы содержимого.
Наиболее распространенная форма взаимодействия с содержимым и master страницы происходит из страницы содержимого. Однако страница master может привести текущую страницу содержимого в действие, и такая функциональность может потребоваться, если страница master содержит элементы пользовательского интерфейса, позволяющие пользователям изменять данные, которые также отображаются на странице содержимого. Рассмотрим страницу содержимого, отображающую сведения о продуктах в элементе управления GridView, и страницу master, содержащую элемент управления Кнопка, который при щелчке удвоит цены на все продукты. Как и в примере из предыдущего руководства, GridView необходимо обновить после нажатия кнопки двойной цены, чтобы отобразить новые цены, но в этом сценарии это страница master, на которую нужно включить страницу содержимого в действие.
В этом руководстве рассматривается, как определить функциональность вызова страницы master на странице содержимого.
Подстрекательство программного взаимодействия с помощью событий и обработчиков событий
Вызов функций страницы содержимого со страницы master сложнее, чем наоборот. Поскольку страница содержимого имеет одну страницу master, при подстрекательстве программного взаимодействия со страницы содержимого мы знаем, какие открытые методы и свойства доступны в нашем распоряжении. Однако страница master может содержать множество разных страниц содержимого, каждая из которых имеет собственный набор свойств и методов. Как мы можем написать код на странице master, чтобы выполнить какое-либо действие на странице содержимого, если мы не знаем, какая страница содержимого будет вызываться до выполнения?
Рассмотрим веб-элемент управления ASP.NET, например элемент управления Кнопка. Элемент управления Кнопка может отображаться на любом количестве ASP.NET страниц и нуждается в механизме, с помощью которого он может оповещать страницу о том, что она была нажата. Это достигается с помощью событий. В частности, элемент управления Button вызывает событие Click
при щелчке; страница ASP.NET, содержащая Кнопку, может при необходимости реагировать на это уведомление с помощью обработчика событий.
Этот же шаблон можно использовать для использования функции триггера страницы master на страницах содержимого:
- Добавьте событие на страницу master.
- Создавайте событие всякий раз, когда страница master должна взаимодействовать со своей страницей содержимого. Например, если странице master нужно предупредить свою страницу содержимого о том, что пользователь удвоил цены, событие будет повышено сразу после удвоение цен.
- Создайте обработчик событий на страницах содержимого, которые должны выполнить определенные действия.
В оставшейся части этого руководства реализуется пример, описанный во введении. а именно страница содержимого со списком продуктов в базе данных и страница master с элементом управления Кнопка, чтобы удвоить цены.
Шаг 1. Отображение продуктов на странице содержимого
Первым делом мы создадим страницу содержимого со списком продуктов из базы данных Northwind. (Мы добавили базу данных Northwind в проект в предыдущем руководстве Взаимодействие с главной страницей из страницы содержимого.) Начните с добавления новой страницы ASP.NET в ~/Admin
папку с именем Products.aspx
, обязательно привязав ее к Site.master
странице master. На рисунке 1 показана Обозреватель решений после добавления этой страницы на веб-сайт.
Рис. 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
.
Рис. 02. Привязка GridView к новому элементу управления SqlDataSource (щелкните для просмотра полноразмерного изображения)
Настройте мастер таким образом, чтобы он использовал базу данных Northwind. Если вы работали с предыдущим руководством, у вас уже должна быть строка подключения с именем NorthwindConnectionString
в Web.config
. Выберите этот строка подключения из раскрывающегося списка, как показано на рисунке 3.
Рис. 03. Настройка SqlDataSource для использования базы данных Northwind (щелкните для просмотра полноразмерного изображения)
Затем укажите оператор элемента управления SELECT
источником данных, выбрав таблицу Products в раскрывающемся списке ProductName
и возвратив столбцы и UnitPrice
(см. рис. 4). Нажмите кнопку Далее, а затем — Готово, чтобы завершить работу мастера настройки источника данных.
Рис. 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>
Рис. 05. Каждый продукт и его цена указаны в GridView (Щелкните для просмотра полноразмерного изображения)
Примечание
Вы можете очистить внешний вид GridView. Некоторые варианты включают форматирование отображаемого значения UnitPrice в виде валюты и использование цветов фона и шрифтов для улучшения внешнего вида сетки. Дополнительные сведения о отображении и форматировании данных в ASP.NET см. в серии руководств по работе с данными.
Шаг 2. Добавление кнопки "Двойные цены" на главную страницу
Следующей задачей является добавление веб-элемента управления "Кнопка" на страницу master, которая при щелчке удвоит цену всех продуктов в базе данных. Откройте страницу Site.master
master и перетащите кнопку с панели элементов на 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.
Рис. 06. Настройка SqlDataSource для использования NorthwindConnectionString
(щелкните для просмотра полноразмерного изображения)
Чтобы задать UpdateCommand
свойство, найдите параметр UpdateQuery в окно свойств. При выборе этого свойства отображается кнопка с многоточием; Нажмите эту кнопку, чтобы открыть диалоговое окно Редактор команды и параметры, показанное на рисунке 7. В текстовое поле диалогового окна введите следующую UPDATE
инструкцию:
UPDATE Products SET UnitPrice = UnitPrice * 2
Этот оператор при выполнении удвоит UnitPrice
значение для каждой Products
записи в таблице.
Рис. 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 void DoublePrice_Click(object sender, EventArgs e)
{
// Double the prices
DoublePricesDataSource.Update();
}
Чтобы протестировать эту функцию, перейдите на страницу ~/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 eventDelegate eventName;
Так как нам нужно оповещать страницу содержимого, только когда пользователь нажал DoublePrice
кнопку и не нужно передавать другие дополнительные сведения, мы можем использовать делегат EventHandler
события , который определяет обработчик событий, который принимает в качестве второго параметра объект типа System.EventArgs
. Чтобы создать событие на странице master, добавьте следующую строку кода в класс кода программной части страницы master:
public partial class Site : System.Web.UI.MasterPage
{
public event EventHandler PricesDoubled;
...
}
Приведенный выше код добавляет общедоступное событие на страницу master с именем PricesDoubled
. Теперь нам нужно поднять это событие после того, как цены были удвоены. Чтобы вызвать событие, используйте следующий синтаксис:
if (eventName != null)
eventName(sender, eventArgs);
Где sender и eventArgs — это значения, которые необходимо передать обработчику событий подписчика.
Обновите DoublePrice
Click
обработчик событий, используя следующий код:
protected void DoublePrice_Click(object sender, EventArgs e)
{
// Double the prices
DoublePricesDataSource.Update();
// Refresh RecentProducts
RecentProducts.DataBind();
// Raise the PricesDoubled event
if (PricesDoubled != null)
PricesDoubled(this, EventArgs.Empty);
}
Как и ранее, Click
обработчик событий начинается с вызова DoublePricesDataSource
метода элемента управления Update
SqlDataSource, чтобы удвоить цены на все продукты. После этого есть два дополнения к обработчику событий. RecentProducts
Сначала обновляются данные GridView. Этот элемент GridView был добавлен на страницу master в предыдущем руководстве и отображает пять последних добавленных продуктов. Нам нужно обновить эту сетку, чтобы она отображала только что удвоив цены на эти пять продуктов. После этого PricesDoubled
возникает событие . Ссылка на саму страницу master (this
) отправляется обработчику событий в качестве источника события, а пустой EventArgs
объект отправляется в качестве аргументов события.
Шаг 4. Обработка события на странице содержимого
На этом этапе страница master вызывает событие PricesDoubled
при каждом щелчке DoublePrice
элемента управления Кнопка. Тем не менее, это только половина битвы - нам по-прежнему нужно обрабатывать событие в подписчике. Это включает два шага: создание обработчика событий и добавление кода подключения событий, чтобы при возникновении события выполнялся обработчик событий.
Начните с создания обработчика событий с именем Master_PricesDoubled
. Из-за того, как мы определили PricesDoubled
событие на странице master, два входных параметра обработчика событий должны иметь типы Object
и EventArgs
соответственно. В обработчике событий вызовите ProductsGrid
метод GridView DataBind
для повторной привязки данных к сетке.
private void Master_PricesDoubled(object sender, EventArgs e)
{
// Rebind data to ProductsGrid
ProductsGrid.DataBind();
}
Код обработчика событий завершен, но нам еще предстоит подключить событие страницы PricesDoubled
master к этому обработчику событий. Подписчик подключает событие к обработчику событий с помощью следующего синтаксиса:
publisher.eventName += new eventDelegate(methodName);
publisher — это ссылка на объект, который предлагает eventName, а methodName — имя обработчика событий, определенного в подписчике, который имеет сигнатуру, соответствующую eventDelegate. Иными словами, если делегатом события является EventHandler
, то methodName должно быть именем метода в подписчике, который не возвращает значение и принимает два входных параметра типов Object
и EventArgs
соответственно.
Этот код подключения событий должен выполняться при первом посещении страницы и последующих обратных передач и должен происходить в точке жизненного цикла страницы, предшествующей возникновению события. Хорошее время для добавления кода подключения событий находится на этапе PreInit, который происходит очень рано в жизненном цикле страницы.
Откройте ~/Admin/Products.aspx
и создайте Page_PreInit
обработчик событий:
protected void Page_PreInit(object sender, EventArgs e)
{
// TODO: Put event wiring logic here
}
Для выполнения этого кода подключения требуется программная ссылка на страницу master со страницы содержимого. Как отмечалось в предыдущем руководстве, это можно сделать двумя способами:
- Путем приведения слабо типизированного
Page.Master
свойства к соответствующему типу страницы master, или - Путем
@MasterType
добавления директивы на страницу.aspx
и последующего использования строго типизированногоMaster
свойства.
Давайте воспользуемся последним подходом. Добавьте следующую @MasterType
директиву в верхнюю часть декларативной разметки страницы:
<%@ MasterType VirtualPath="~/Site.master" %>
Затем добавьте следующий код подключения событий в Page_PreInit
обработчик событий:
protected void Page_PreInit(object sender, EventArgs e)
{
// Create an event handler for the master page's PricesDoubled event
Master.PricesDoubled += new EventHandler(Master_PricesDoubled);
}
При использовании этого кода элемент GridView на странице содержимого обновляется при каждом нажатии кнопки DoublePrice
.
Это поведение показано на рисунках 8 и 9. На рисунке 8 показана страница при первом посещении. Обратите внимание, что значения price в RecentProducts
GridView (в левом столбце страницы master) и ProductsGrid
GridView (на странице содержимого). На рис. 9 показан тот же экран сразу после DoublePrice
нажатия кнопки. Как видите, новые цены мгновенно отражаются в обоих GridView.
Рис. 08. Начальные значения цен (щелкните, чтобы просмотреть полноразмерное изображение)
Рис. 09. Цены Just-Doubled отображаются в GridViews (Щелкните, чтобы просмотреть полноразмерное изображение)
Сводка
В идеале страница master и страницы ее содержимого полностью отделены друг от друга и не требуют никакого уровня взаимодействия. Однако если у вас есть master страница или страница содержимого, на которых отображаются данные, которые можно изменить с master страницы или страницы содержимого, может потребоваться, чтобы страница master оповещала страницу содержимого (или наоборот) при изменении данных, чтобы можно было обновить отображение. В предыдущем руководстве мы узнали, как настроить программное взаимодействие страницы содержимого со страницей master. В этом руководстве мы рассмотрели, как инициировать взаимодействие с master страницей.
Хотя программное взаимодействие между содержимым и master страницей может происходить из содержимого или master страницы, используемый шаблон взаимодействия зависит от источника. Различия обусловлены тем, что страница содержимого имеет одну страницу master, но на master странице может быть много разных страниц содержимого. Вместо того чтобы master страница напрямую взаимодействовала со страницей содержимого, лучший подход заключается в том, чтобы master страница вызывала событие, сигналив о выполнении какого-либо действия. Те страницы содержимого, которые заботятся о действии, могут создавать обработчики событий.
Счастливое программирование!
Дополнительные материалы
Дополнительные сведения по темам, рассматриваемым в этом руководстве, см. в следующих ресурсах:
- Доступ к данным и их обновление в ASP.NET
- События и делегаты
- Передача информации между содержимым и эталонной страницами
- Работа с данными в руководствах по ASP.NET
Об авторе
Скотт Митчелл (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
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по