Поделиться через


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

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

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

Введение

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

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

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

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

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

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

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

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

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

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

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

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

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

Помните, что в руководстве по указанию заголовка, метатегов и других заголовков HTML мы создали пользовательский базовый класс BasePage страницы, который создает заголовок страницы, если он не задан явным образом. Перейдите к Products.aspx классу code-behind страницы и наследуйтесь от него (а не от 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 из таблицы

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

Это все. После завершения работы мастера Visual Studio добавляет два BoundFields в 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 на главную страницу, которая при щелчке удвоит цену всех продуктов в базе данных. Site.master Откройте главную страницу и перетащите кнопку из панели элементов в конструктор, поместив ее под RecentProductsDataSource элементом управления SqlDataSource, который мы добавили в предыдущем руководстве. Присвойте свойству DoublePrice Text Button ID значение "Double Product Prices".

Затем добавьте элемент управления SqlDataSource на главную страницу, назвав его 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 и добавьте следующий код:

protected void DoublePrice_Click(object sender, EventArgs e)
{
    // Double the prices
    DoublePricesDataSource.Update();
}

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

Шаг 3. Повышение события при двойных ценах

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

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

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

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

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

Примечание.

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

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

public event eventDelegate eventName;

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

public partial class Site : System.Web.UI.MasterPage
{
    public event EventHandler PricesDoubled;

    ...
}

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

if (eventName != null)
    eventName(sender, eventArgs);

Где отправитель и 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 был добавлен на главную страницу в предыдущем руководстве и отображает пять последних добавленных продуктов. Нам нужно обновить эту сетку, чтобы она отображала только что удвоительные цены на эти пять продуктов. После этого PricesDoubled вызывается событие. Ссылка на саму главную страницу (this) отправляется обработчику событий в качестве источника события, а пустой EventArgs объект отправляется в качестве аргументов события.

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

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

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

private void Master_PricesDoubled(object sender, EventArgs e)
{
    // Rebind data to ProductsGrid
    ProductsGrid.DataBind();
}

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

publisher.eventName += new eventDelegate(methodName);

Publisher — это ссылка на объект, который предлагает событие eventName, а methodName — имя обработчика событий, определенного в подписчике, который имеет подпись, соответствующую событиюDelegate. Другими словами, если делегат события равенEventHandler, имя метода в подписчике, которое не возвращает значение и принимает два входных параметра типов Object и EventArgsсоответственно.

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

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

protected void Page_PreInit(object sender, EventArgs e)
{
    // TODO: Put event wiring logic here
}

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

  • Приведение свободно типизированного Page.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 показана страница при первом посещении. Обратите внимание, что значения цен в RecentProducts GridView (в левом столбце главной страницы) и ProductsGrid GridView (на странице содержимого). На рисунке 9 показан тот же экран сразу после DoublePrice нажатия кнопки. Как вы видите, новые цены мгновенно отражаются в обоих GridViews.

Начальные значения цен

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

В GridViews отображаются только что двойные цены

Рис. 09. В GridViews отображаются только двойные цены (щелкните, чтобы просмотреть изображение полного размера)

Итоги

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

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

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

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

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

Об авторе

Скотт Митчелл, автор нескольких книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с технологиями Microsoft Web с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Сэмс Учит себя ASP.NET 3,5 в 24 часах. Скотт можно получить по mitchell@4GuysFromRolla.com адресу или через свой блог.http://ScottOnWriting.NET

Особое спасибо

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