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


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

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

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

Введение

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

Нам еще предстоит изучить, как страница master и страница содержимого могут взаимодействовать программными средствами. Помимо определения разметки для элементов управления ContentPlaceHolder страницы master, страница содержимого также может назначать значения общедоступным свойствам своей master страницы и вызывать ее открытые методы. Аналогичным образом страница master может взаимодействовать со страницами содержимого. Хотя программное взаимодействие между master и страницей содержимого является менее распространенным, чем взаимодействие между декларативными разметками, существует множество сценариев, в которых такое программное взаимодействие требуется.

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

Примеры программного взаимодействия между страницей содержимого и ее главной страницей

Если определенную область страницы необходимо настроить постранично, мы используем элемент управления ContentPlaceHolder. Но как насчет ситуаций, когда большинство страниц должны выдавать определенные выходные данные, а небольшое количество страниц нужно настроить, чтобы показать что-то другое? Один из таких примеров, который мы рассмотрели в учебнике Multiple ContentPlaceHolders and Default Content, включает отображение интерфейса входа на каждой странице. Хотя большинство страниц должно содержать интерфейс входа, он должен подавляться для нескольких страниц, таких как страница main входа (Login.aspx); страница Создания учетной записи и другие страницы, доступные только для пользователей, прошедших проверку подлинности. В учебнике Multiple ContentPlaceHolders and Default Content было показано, как определить содержимое по умолчанию для ContentPlaceHolder на странице master, а затем переопределить его на тех страницах, где содержимое по умолчанию не требуется.

Другой вариант — создать открытое свойство или метод на странице master, который указывает, следует ли отображать или скрывать интерфейс входа. Например, страница master может содержать открытое свойство с именем ShowLoginUI , значение которого использовалось для задания Visible свойства элемента управления Login на странице master. Страницы содержимого, на которых должен подавляться пользовательский интерфейс входа, могут программно задать ShowLoginUI для свойства значение False.

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

Когда пользователь посещает страницу для добавления новой записи, он видит пять последних добавленных записей, отображаемых на странице master. После заполнения значений для столбцов новой записи она отправляет форму. Предположим, что свойство GridView на странице EnableViewState master имеет значение True (значение по умолчанию), его содержимое перезагружается из состояния представления и, следовательно, отображаются пять одинаковых записей, даже если в базу данных только что добавлена новая запись. Это может сбить с толку пользователя.

Примечание

Даже если вы отключите состояние представления GridView, чтобы оно повторно привязывалось к базовому источнику данных при каждой обратной отправке, оно по-прежнему не будет отображать только что добавленную запись, так как данные привязаны к GridView раньше в жизненном цикле страницы, чем при добавлении новой записи в базу данных.

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

Так как обновление отображения страницы master из обработчика событий на странице содержимого является одной из наиболее распространенных потребностей в содержимом и master взаимодействии со страницей, давайте рассмотрим этот раздел более подробно. Скачивание этого руководства включает базу данных Microsoft SQL Server 2005, экспресс-выпуск с именем NORTHWIND.MDF в папке App_Data веб-сайта. В базе данных Northwind хранятся сведения о продуктах, сотрудниках и продажах для вымышленной компании Northwind Traders.

Шаг 1 содержит пошаговые инструкции по отображению пяти последних добавленных продуктов в GridView на странице master. На шаге 2 создается страница содержимого для добавления новых продуктов. На шаге 3 рассматривается создание открытых свойств и методов на странице master, а на шаге 4 показано, как программно интерфейсировать с этими свойствами и методами на странице содержимого.

Примечание

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

Шаг 1. Отображение пяти последних добавленных продуктов на главной странице

Откройте сайт. master master страницу и добавьте элемент управления Label и GridView в leftContent<div>. Очистите свойство LabelText, присвойте свойству FalseEnableViewState значение , а свойству ID — значение GridMessage; задайте для свойства GridView ID значение RecentProducts. Затем в Designer разверните смарт-тег GridView и привяжите его к новому источнику данных. Откроется мастер настройки источника данных. Так как база данных Northwind в папке App_Data является базой данных Microsoft SQL Server, выберите создать SqlDataSource, выбрав (см. рис. 1); назовите SqlDataSource RecentProductsDataSource.

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

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

На следующем шаге нам нужно указать, к какой базе данных следует подключиться. NORTHWIND.MDF Выберите файл базы данных в раскрывающемся списке и нажмите кнопку Далее. Так как мы впервые используем эту базу данных, мастер предложит сохранить строка подключения в Web.config. Сохраните строка подключения с именем NorthwindConnectionString.

Подключение к базе данных Northwind

Рис. 02. Подключение к базе данных Northwind (щелкните, чтобы просмотреть полноразмерное изображение)

Мастер настройки источника данных предоставляет два способа, с помощью которых можно указать запрос, используемый для получения данных:

  • Путем указания пользовательской инструкции SQL или хранимой процедуры;
  • Путем выбора таблицы или представления, а затем указания возвращаемых столбцов

Так как мы хотим вернуть только пять последних добавленных продуктов, необходимо указать пользовательскую инструкцию SQL. Используйте следующий SELECT запрос:

SELECT TOP 5 ProductName, UnitPrice FROM Products ORDER BY ProductID DESC

Ключевое слово TOP 5 возвращает только первые пять записей из запроса. Первичный Products ключ таблицы — ProductIDэто IDENTITY столбец, который гарантирует, что каждый новый продукт, добавленный в таблицу, будет иметь большее значение, чем предыдущая запись. Таким образом, сортировка результатов по ProductID убыванию возвращает продукты, начиная с последних созданных.

Возврат пяти последних добавленных продуктов

Рис. 03. Возврат пяти последних добавленных продуктов (щелкните для просмотра полноразмерного изображения)

После завершения работы мастера Visual Studio создает два BoundField для GridView для отображения ProductName полей и UnitPrice , возвращенных из базы данных. На этом этапе декларативная разметка страницы master должна содержать следующую разметку:

<asp:Label ID="GridMessage" runat="server" EnableViewState="false"></asp:Label> 
<asp:GridView ID="RecentProducts" runat="server" AutoGenerateColumns="False" 
 DataSourceID="RecentProductsDataSource">
 <Columns> 
 <asp:BoundField DataField="ProductName" HeaderText="ProductName" 
 SortExpression="ProductName" /> 
 <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice" 
 SortExpression="UnitPrice" /> 
 </Columns> 
</asp:GridView> 
<asp:SqlDataSource ID="RecentProductsDataSource" runat="server" 
 ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>" 
 SelectCommand="SELECT TOP 5 ProductName, UnitPrice FROM Products ORDER BY ProductID DESC"> 
</asp:SqlDataSource>

Как видите, разметка содержит: веб-элемент управления Label (GridMessage); GridView RecentProductsс двумя BoundFields и элемент управления SqlDataSource, который возвращает пять последних добавленных продуктов.

После создания этого элемента управления GridView и настройки элемента управления SqlDataSource посетите веб-сайт через браузер. Как показано на рисунке 4, в левом нижнем углу появится сетка с пятью последними добавленными продуктами.

GridView отображает пять последних добавленных продуктов

Рис. 04. GridView отображает пять последних добавленных продуктов (щелкните для просмотра полноразмерного изображения)

Примечание

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

Шаг 2. Создание страницы содержимого для добавления новых продуктов

Следующая задача — создать страницу содержимого, с которой пользователь может добавить новый продукт в таблицу Products . Добавьте новую страницу содержимого в папку Admin с именем AddProduct.aspx, обязательно привязав ее к Site.master странице master. На рисунке 5 показана Обозреватель решений после добавления этой страницы на веб-сайт.

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

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

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

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

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

Как показано на рисунке 6, добавление этого <siteMapNode> элемента отражено в списке Уроки.

Вернитесь к AddProduct.aspx. В элементе управления Контент для MainContent ContentPlaceHolder добавьте элемент управления DetailsView и назовите его NewProduct. Привяжите DetailsView к новому элементу управления SqlDataSource с именем NewProductDataSource. Как и в случае с SqlDataSource на шаге 1, настройте мастер таким образом, чтобы он использовал базу данных Northwind, и выберите, чтобы указать пользовательскую инструкцию SQL. Так как DetailsView будет использоваться для добавления элементов в базу данных, необходимо указать как оператор, SELECT так и INSERT оператор . Используйте следующий SELECT запрос:

SELECT ProductName, UnitPrice FROM Products

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

INSERT INTO Products(ProductName, UnitPrice) VALUES(@ProductName, @UnitPrice)

После завершения работы мастера перейдите к смарт-тегу DetailsView и проверка флажок "Включить вставку". При этом commandField добавляется в DetailsView со свойством ShowInsertButton True. Так как этот DetailsView будет использоваться исключительно для вставки данных, задайте свойству DetailsView DefaultMode значение Insert.

Вот и все! Давайте протестируем эту страницу. Посетите AddProduct.aspx через браузер, введите имя и цену (см. рис. 6).

Добавление нового продукта в базу данных

Рис. 06. Добавление нового продукта в базу данных (щелкните для просмотра полноразмерного изображения)

Введя название и цену нового продукта, нажмите кнопку Вставить. Это приводит к обратной отправке формы. При обратной отправке выполняется инструкция элемента управления INSERT SqlDataSource; два его параметра заполняются введенными пользователем значениями в двух элементах управления TextBox DetailsView. К сожалению, визуальные отзывы о вставке отсутствуют. Было бы неплохо отобразить сообщение с подтверждением того, что добавлена новая запись. Я оставляю это как упражнение для читателя. Кроме того, после добавления новой записи из DetailsView gridView на странице master по-прежнему отображаются те же пять записей, что и раньше. В нее не входит только что добавленная запись. Мы рассмотрим, как устранить эту проблему в следующих шагах.

Примечание

Помимо добавления визуальной обратной связи о том, что вставка выполнена успешно, рекомендуется также обновить интерфейс вставки DetailsView, чтобы включить проверку. В настоящее время проверка не выполняется. Если пользователь вводит недопустимое значение для UnitPrice поля, например "Слишком дорого", при обратной отправке создается исключение, когда система пытается преобразовать строку в десятичное значение. Дополнительные сведения о настройке интерфейса вставки см. в руководстве По настройке интерфейса изменения данных из серии руководств по работе с данными.

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

На шаге 1 мы добавили элемент управления GridMessage Label Web над GridView на странице master. Эта метка предназначена для дополнительного отображения сообщения. Например, после добавления новой записи в таблицу Products может потребоваться отобразить сообщение "ProductName добавлено в базу данных". Вместо жесткого написания текста для этой метки на странице master может потребоваться настроить сообщение на странице содержимого.

Так как элемент управления Label реализуется как защищенная переменная-член на странице master, доступ к нему напрямую со страниц содержимого невозможен. Для работы с меткой на странице master со страницы содержимого (или, если на то пошло, с любым веб-элементом управления на странице master) необходимо создать на странице master открытое свойство, которое предоставляет веб-элемент управления или служит прокси-сервером, с помощью которого можно получить доступ к одному из его свойств. Добавьте следующий синтаксис в класс кода программной части страницы master, чтобы предоставить свойство LabelText:

Public Property GridMessageText() As String 
 Get
 Return GridMessage.Text 
 End Get 
 Set(ByVal Value As String) 
 GridMessage.Text = Value 
 End Set 
End Property

При добавлении новой записи в таблицу Products со страницы RecentProducts содержимого GridView на странице master необходимо повторно привязываться к базовому источнику данных. Чтобы повторно привязать GridView, вызовите его DataBind метод . Так как GridView на странице master недоступен программным способом для страниц содержимого, необходимо создать открытый метод на странице master, который при вызове повторно привязывает данные к GridView. Добавьте следующий метод в класс кода программной части страницы master:

Public Sub RefreshRecentProductsGrid() 
 RecentProducts.DataBind()
End Sub

При наличии GridMessageText свойства и RefreshRecentProductsGrid метода любая страница содержимого может программно задать или прочитать значение GridMessage свойства Label Text или повторно привязать данные к RecentProducts GridView. В шаге 4 рассматривается, как получить доступ к общедоступным свойствам и методам страницы master со страницы содержимого.

Примечание

Не забудьте пометить свойства и методы страницы master как Public. Если явно не обозначить эти свойства и методы как Public, они не будут доступны на странице содержимого.

Шаг 4. Вызов открытых участников главной страницы из страницы содержимого

Теперь, когда страница master содержит необходимые открытые свойства и методы, мы готовы вызвать эти свойства и методы на странице содержимогоAddProduct.aspx. В частности, необходимо задать свойство страницы GridMessageText master и вызвать его RefreshRecentProductsGrid метод после добавления нового продукта в базу данных. Все ASP.NET веб-элементы управления данными запускают события непосредственно перед и после выполнения различных задач, что позволяет разработчикам страниц легко выполнять некоторые программные действия до или после задачи. Например, когда пользователь нажимает кнопку Вставка DetailsView, при обратной отправке DetailsView вызывает событие ItemInserting перед началом рабочего процесса вставки. Затем запись вставляется в базу данных. После этого DetailsView вызывает событие ItemInserted . Поэтому для работы со страницей master после добавления нового продукта создайте обработчик события DetailsViewItemInserted.

Существует два способа программного взаимодействия страницы содержимого со страницей master.

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

Рассмотрим оба подхода.

Использование свойства "Слабо типизированныйPage.Master"

Все ASP.NET веб-страницы должны быть производными Page от класса , который находится в System.Web.UI пространстве имен. Класс Page включает Master свойство , возвращающее ссылку на страницу master страницы. Если на странице нет master страница Master возвращает .Nothing

Свойство Master возвращает объект типа MasterPage (также расположенный в System.Web.UI пространстве имен), который является базовым типом, от которого являются все master страницы. Поэтому для использования открытых свойств или методов, определенных на странице master веб-сайта, необходимо привести MasterPage объект, возвращаемый из Master свойства, к соответствующему типу. Так как мы назвали файл master страницы Site.master, класс кода программной части получил имя Site. Поэтому следующий код приводит Page.Master свойство к экземпляру Site класса .

' Cast the loosely-typed Page.Master property and then set the GridMessageText property 
Dim myMasterPage As Site = CType(Page.Master, Site)

Теперь, когда мы привялили слабо типизированное Page.Master свойство к типу Site, мы можем ссылаться на свойства и методы, относящиеся к Site. Как показано на рисунке 7, свойство GridMessageText public отображается в раскрывающемся списке IntelliSense.

IntelliSense показывает общедоступные свойства и методы главной страницы

Рис. 07. IntelliSense Показывает общедоступные свойства и методы главной страницы (щелкните для просмотра полноразмерного изображения)

Примечание

Если вы назвали файл MasterPage.master master страницы, то для класса код программной части страницы master будет присвоено MasterPageзначение . Это может привести к неоднозначности кода при приведение типа System.Web.UI.MasterPage к классу MasterPage . Короче говоря, необходимо полностью определить тип, к которому выполняется приведение, что может быть немного сложно при использовании модели проекта веб-сайта. Я хотел бы либо убедиться, что при создании страницы master вы назовете ее нечто отличное MasterPage.master от или, что еще лучше, создать строго типизированную ссылку на страницу master.

Создание ссылки Strongly-Typed с помощью директивы@MasterType

При внимательном просмотре можно увидеть, что класс кода программной части страницы ASP.NET является разделяемым классом (обратите внимание на Partial ключевое слово в определении класса). Разделяемые классы появились в C# и Visual Basic with.NET Framework 2.0 и, в двух словах, позволяют определять члены класса в нескольких файлах. Файл класса программной части , AddProduct.aspx.vbнапример, содержит код, который мы, разработчик страницы, создаем. В дополнение к нашему коду подсистема ASP.NET автоматически создает отдельный файл класса со свойствами и обработчиками событий, которые преобразуют декларативную разметку в иерархию классов страницы.

Автоматическое создание кода, которое происходит при посещении ASP.NET страницы, открывает путь для некоторых довольно интересных и полезных возможностей. В случае master страниц, если мы сообщаем подсистеме ASP.NET, какая страница master используется нашей страницей контента, она создает строго типизированное Master свойство для нас.

Используйте директиву@MasterType , чтобы сообщить обработчику ASP.NET о типе страницы master содержимого. Директива @MasterType может принимать имя типа страницы master или путь к файлу. Чтобы указать, что AddProduct.aspx страница использует в Site.master качестве master страницы, добавьте следующую директиву в начало :AddProduct.aspx

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

Эта директива предписывает подсистеме ASP.NET добавить строго типизированную ссылку на страницу master с помощью свойства с именем Master. Используя директиву @MasterType , мы можем вызывать Site.master открытые свойства и методы страницы master непосредственно через Master свойство без приведения.

Примечание

Если опустить директиву@MasterType, синтаксис Page.Master и вернуть одно и Master то же: слабо типизированный объект на страницу master страницы. При включении директивы @MasterTypeMaster возвращается строго типизированная ссылка на указанную страницу master. Page.Masterоднако по-прежнему возвращает ссылку со слабой типикой. Более подробные сведения о том, почему это так и как Master создается свойство при @MasterType включении директивы, см. в записи @MasterTypeблога К. Скотта Аллена в ASP.NET 2.0.

Обновление главной страницы после добавления нового продукта

Теперь, когда мы знаем, как вызывать открытые свойства и методы страницы master со страницы контента, мы готовы обновить AddProduct.aspx страницу, чтобы после добавления нового продукта обновлялась страница master. В начале шага 4 мы создали обработчик событий для события элемента управления ItemInserting DetailsView, который выполняется сразу после добавления нового продукта в базу данных. Добавьте следующий код в этот обработчик событий:

Protected Sub NewProduct_ItemInserted(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DetailsViewInsertedEventArgs) Handles NewProduct.ItemInserted
 ' Cast the loosely-typed Page.Master property and then set the GridMessageText property 
 Dim myMasterPage As Site = CType(Page.Master, Site) 
 myMasterPage.GridMessageText = String.Format("{0} added to grid...", e.Values("ProductName"))
 ' Use the strongly-typed Master property 
 Master.RefreshRecentProductsGrid()
End Sub

В приведенном выше коде используются свойства слабого типа Page.Master и строго типизированные Master свойства. Обратите внимание, что GridMessageText для свойства задано значение "ProductName добавлено в сетку..." Значения только что добавленного продукта доступны через коллекцию e.Values . Как видите, доступ к добавленным ProductName значениям осуществляется через e.Values("ProductName").

На рисунке 8 показана AddProduct.aspx страница сразу после добавления нового продукта — Соды Скотта — в базу данных. Обратите внимание, что только что добавленное название продукта указано в метке страницы master и что GridView был обновлен, чтобы включить продукт и его цену.

Метка главной страницы и GridView, показывающие Just-Added продукт

Рис. 08. Метка главной страницы и GridView Отображение Just-Added продукта (щелкните для просмотра полноразмерного изображения)

Сводка

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

Хорошая новость заключается в том, что страница содержимого программно взаимодействует со своей master страницей. Начните с создания общедоступных свойств или методов на странице master, которые инкапсулируют функциональные возможности, которые должны вызываться страницей содержимого. Затем на странице содержимого получите доступ к свойствам и методам страницы master через слабо типизированное Page.Master свойство или используйте директиву @MasterType , чтобы создать строго типизированную ссылку на страницу 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