Настраиваемые кнопки в элементах управления DataList и Repeater (VB)
В этом руководстве мы создадим интерфейс, который использует Repeater для перечисления категорий в системе, при этом каждая категория предоставляет кнопку для отображения связанных продуктов с помощью элемента управления BulletedList.
Введение
В последних семнадцати руководствах по DataList и Repeater мы создавали примеры только для чтения и примеры редактирования и удаления. Чтобы упростить редактирование и удаление возможностей в DataList, мы добавили кнопки в dataList ItemTemplate
, которые при нажатии вызывают обратную передачу и вызывают событие DataList, соответствующее свойству кнопки CommandName
. Например, добавление кнопки в ItemTemplate
объект со значением CommandName
свойства Edit приводит к тому, что dataList EditCommand
срабатывает при обратной отправке; один с параметром CommandName
Delete вызывает DeleteCommand
.
Помимо кнопок "Изменить" и "Удалить", элементы управления DataList и Repeater также могут включать кнопки, linkButtons или ImageButtons, которые при щелчке выполняют пользовательскую логику на стороне сервера. В этом руководстве мы создадим интерфейс, который использует Repeater для перечисления категорий в системе. Для каждой категории repeater будет включать кнопку для отображения продуктов, связанных с категорией, с помощью элемента управления BulletedList (см. рис. 1).
Рис. 1. При щелчке по ссылке Показать продукты отображаются категории "Продукты" в маркированных списках (щелкните для просмотра полноразмерного изображения)
Шаг 1. Добавление веб-страниц руководства по пользовательским кнопкам
Прежде чем мы рассмотрим, как добавить пользовательскую кнопку, сначала уделим время созданию ASP.NET страниц в проекте веб-сайта, который понадобится для работы с этим руководством. Начните с добавления новой папки с именем CustomButtonsDataListRepeater
. Затем добавьте следующие две страницы ASP.NET в папку, чтобы связать каждую страницу со страницей Site.master
master:
Default.aspx
CustomButtons.aspx
Рис. 2. Добавление страниц ASP.NET для руководств по пользовательским Buttons-Related
Как и в других папках, Default.aspx
в папке CustomButtonsDataListRepeater
будет отображаться список учебников в своем разделе. Помните, что SectionLevelTutorialListing.ascx
пользовательский элемент управления предоставляет эту функцию. Добавьте этот пользовательский элемент управления в , Default.aspx
перетащив его из Обозреватель решений в режим конструктора страницы.
Рис. 3. Добавление пользовательского SectionLevelTutorialListing.ascx
элемента управления в Default.aspx
(щелкните для просмотра полноразмерного изображения)
Наконец, добавьте страницы в качестве записей в Web.sitemap
файл. В частности, добавьте следующую разметку после разбиения по страницам и сортировки с помощью DataList и Repeater <siteMapNode>
:
<siteMapNode
url="~/CustomButtonsDataListRepeater/Default.aspx"
title="Adding Custom Buttons to the DataList and Repeater"
description="Samples of DataList and Repeater Reports that Include
Buttons for Performing Server-Side Actions">
<siteMapNode
url="~/CustomButtonsDataListRepeater/CustomButtons.aspx"
title="Using Custom Buttons in the DataList and Repeater's Templates"
description="Examines how to add custom Buttons, LinkButtons,
or ImageButtons within templates." />
</siteMapNode>
После обновления Web.sitemap
просмотрите веб-сайт учебников в браузере. Меню слева теперь содержит элементы для редактирования, вставки и удаления учебников.
Рис. 4. Схема сайта теперь включает запись для руководства по пользовательским кнопкам
Шаг 2. Добавление списка категорий
Для работы с этим руководством необходимо создать средство repeater, в котором перечислены все категории, а также элемент Show Products LinkButton, который при щелчке отображает связанные продукты категории в маркированный список. Сначала создадим простой повторитель, который перечисляет категории в системе. Начните с открытия страницы CustomButtons.aspx
в папке CustomButtonsDataListRepeater
. Перетащите repeater с панели элементов на Designer и задайте для его ID
свойства значение Categories
. Затем создайте новый элемент управления источником данных из смарт-тега Repeater. В частности, создайте новый элемент управления ObjectDataSource с именем CategoriesDataSource
, который выбирает свои данные из CategoriesBLL
метода класса GetCategories()
.
Рис. 5. Настройка ObjectDataSource для использования CategoriesBLL
метода Класса GetCategories()
(щелкните для просмотра полноразмерного изображения)
В отличие от элемента управления DataList, для которого Visual Studio создает значение по умолчанию ItemTemplate
на основе источника данных, шаблоны Repeater необходимо определить вручную. Кроме того, шаблоны Repeater должны создаваться и редактироваться декларативно (то есть в смарт-теге Repeater нет параметра Изменить шаблоны).
Щелкните вкладку Источник в левом нижнем углу и добавьте ItemTemplate
объект , отображающий имя категории в элементе <h3>
и его описание в теге абзаца; включив в SeparatorTemplate
него горизонтальное правило (<hr />
) между каждой категорией. Кроме того, добавьте LinkButton со свойством Text
Show Products. После выполнения этих действий декларативная разметка страницы должна выглядеть следующим образом:
<asp:Repeater ID="Categories" DataSourceID="CategoriesDataSource"
runat="server">
<ItemTemplate>
<h3><%# Eval("CategoryName") %></h3>
<p>
<%# Eval("Description") %>
[<asp:LinkButton runat="server" ID="ShowProducts">
Show Products</asp:LinkButton>]
</p>
</ItemTemplate>
<SeparatorTemplate><hr /></SeparatorTemplate>
</asp:Repeater>
<asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetCategories" TypeName="CategoriesBLL">
</asp:ObjectDataSource>
На рисунке 6 показана страница при просмотре в браузере. В списке указаны имя и описание каждой категории. Кнопка Показать продукты при нажатии вызывает обратную передачу, но пока не выполняет никаких действий.
Рис. 6. Отображается имя и описание каждой категории вместе с элементом Show Products LinkButton (Щелкните, чтобы просмотреть полноразмерное изображение)
Шаг 3. Выполнение Server-Side логики при нажатии кнопки "Показать продукты"
При каждом щелчке элемента Button, LinkButton или ImageButton в шаблоне в DataList или Repeater происходит обратная передача и возникает событие DataList или Repeater ItemCommand
. В дополнение к событию ItemCommand
элемент управления DataList может также вызывать другое, более конкретное событие, если свойству кнопки задана CommandName
одна из зарезервированных строк (Delete, Edit, Cancel, Update или Select ), но ItemCommand
событие всегда вызывается.
При нажатии кнопки в DataList или Repeater часто требуется передать, какая кнопка была нажата (в случае, если в элементе управления может быть несколько кнопок, например изменить и удалить), и, возможно, некоторые дополнительные сведения (например, значение первичного ключа элемента, кнопка которого была нажата). Button, LinkButton и ImageButton предоставляют два свойства, значения которых передаются обработчику ItemCommand
событий:
CommandName
строка, которая обычно используется для идентификации каждой кнопки в шаблоне.CommandArgument
обычно используется для хранения значения некоторого поля данных, например значения первичного ключа.
В этом примере задайте для свойства LinkButton значение CommandName
ShowProducts и привяжите значение CategoryID
первичного ключа текущей записи к свойству CommandArgument
с помощью синтаксиса CategoryArgument='<%# Eval("CategoryID") %>'
привязки данных . После указания этих двух свойств декларативный синтаксис LinkButton должен выглядеть следующим образом:
<asp:LinkButton runat="server" CommandName="ShowProducts"
CommandArgument='<%# Eval("CategoryID") %>' ID="ShowProducts">
Show Products</asp:LinkButton>
При нажатии кнопки происходит обратная передача данных и возникает событие DataList или Repeater ItemCommand
. Обработчику событий передаются значения кнопок CommandName
и CommandArgument
.
Создайте обработчик событий для события Repeater ItemCommand
и обратите внимание на второй параметр, переданный в обработчик событий (с именем e
). Этот второй параметр имеет тип RepeaterCommandEventArgs
и имеет следующие четыре свойства:
CommandArgument
значение свойства "Нажатая кнопка"CommandArgument
CommandName
значение свойства кнопкиCommandName
CommandSource
ссылка на нажатый элемент управления "Кнопка"Item
ссылка наRepeaterItem
объект , содержащий кнопку, которая была нажата; каждая запись, привязанная к repeater, проявляется какRepeaterItem
Так как выбранные категории CategoryID
передаются через CommandArgument
свойство , мы можем получить набор продуктов, связанных с выбранной категорией, в обработчике ItemCommand
событий. Затем эти продукты можно привязать к элементу управления BulletedList в ItemTemplate
(который мы еще не добавили). Все, что осталось, — это добавить bulletedList, сослаться на него в ItemCommand
обработчике событий и привязать к нему набор продуктов для выбранной категории, который мы рассмотрим на шаге 4.
Примечание
Обработчику событий DataList ItemCommand
передается объект типа DataListCommandEventArgs
, который предлагает те же четыре свойства, что и RepeaterCommandEventArgs
класс .
Шаг 4. Отображение продуктов выбранной категории в маркированный список
Выбранные продукты категории могут отображаться в элементах Repeater ItemTemplate
с помощью любого количества элементов управления. Можно добавить еще один вложенный repeater, DataList, DropDownList, GridView и т. д. Так как мы хотим отобразить продукты в виде маркированного списка, мы будем использовать элемент управления BulletedList. Вернувшись к CustomButtons.aspx
декларативной разметке страницы, добавьте элемент управления BulletedList в ItemTemplate
после элемента Show Products LinkButton. Задайте для маркеров BulletedLists значение ID
ProductsInCategory
. BulletedList отображает значение поля данных, указанное с помощью DataTextField
свойства . Так как к этому элементу управления будут привязаны сведения о продукте, присвойте свойству DataTextField
значение ProductName
.
<asp:BulletedList ID="ProductsInCategory" DataTextField="ProductName"
runat="server"></asp:BulletedList>
В обработчике ItemCommand
событий укажите ссылку на этот элемент управления с помощью e.Item.FindControl("ProductsInCategory")
и привяжите его к набору продуктов, связанных с выбранной категорией.
Protected Sub Categories_ItemCommand _
(source As Object, e As RepeaterCommandEventArgs) _
Handles Categories.ItemCommand
If e.CommandName = "ShowProducts" Then
' Determine the CategoryID
Dim categoryID As Integer = Convert.ToInt32(e.CommandArgument)
' Get the associated products from the ProudctsBLL and
' bind them to the BulletedList
Dim products As BulletedList = _
CType(e.Item.FindControl("ProductsInCategory"), BulletedList)
Dim productsAPI As New ProductsBLL()
products.DataSource = productsAPI.GetProductsByCategoryID(categoryID)
products.DataBind()
End If
End Sub
Перед выполнением какого-либо действия в обработчике ItemCommand
событий целесообразно сначала проверка значение входящего CommandName
объекта . ItemCommand
Так как обработчик событий срабатывает при нажатии любой кнопки, при наличии в шаблоне нескольких кнопок используйте CommandName
значение , чтобы определить, какое действие необходимо выполнить. CommandName
Проверка здесь является спорным, так как у нас есть только одна кнопка, но это хорошая привычка, чтобы сформировать. CategoryID
Затем из свойства извлекается объект выбранной CommandArgument
категории. Затем на элемент управления BulletedList в шаблоне добавляется ссылка и привязка к результатам ProductsBLL
метода класса GetProductsByCategoryID(categoryID)
.
В предыдущих руководствах, которые использовали кнопки в DataList, например Общие сведения об изменении и удалении данных в DataList, мы определяли значение первичного ключа данного элемента с помощью DataKeys
коллекции. Хотя этот подход хорошо работает с DataList, repeater не имеет DataKeys
свойства . Вместо этого мы должны использовать альтернативный подход для предоставления значения первичного ключа, например с помощью свойства кнопки CommandArgument
или путем назначения значения первичного ключа скрытому веб-элементу управления Label в шаблоне и считывания его значения обратно в ItemCommand
обработчике событий с помощью e.Item.FindControl("LabelID")
.
Завершив работу обработчика ItemCommand
событий, проверьте эту страницу в браузере. Как показано на рисунке 7, нажатие ссылки Показать продукты вызывает обратную передачу и отображает продукты для выбранной категории в маркированный список. Кроме того, обратите внимание, что эта информация о продукте остается, даже если щелкнули другие категории Показать ссылки продуктов.
Примечание
Если вы хотите изменить поведение этого отчета таким образом, чтобы одновременно отображались только продукты одной категории, просто присвойте свойству элемента управления EnableViewState
BulletedList значение False
.
Рис. 7. Маркированный список используется для отображения продуктов выбранной категории (щелкните для просмотра полноразмерного изображения)
Сводка
Элементы управления DataList и Repeater могут включать любое количество элементов управления Button, LinkButtons или ImageButtons в своих шаблонах. Такие кнопки при нажатии вызывают обратную передачу ItemCommand
и вызывают событие . Чтобы связать пользовательское действие на стороне сервера с нажатой кнопкой, создайте обработчик событий для ItemCommand
события. В этом случае обработчик сначала проверка входящее CommandName
значение, чтобы определить, какая кнопка была нажата. Дополнительные сведения можно дополнительно указать с помощью свойства кнопки CommandArgument
.
Счастливого программирования!
Об авторе
Скотт Митчелл( Scott Mitchell), автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с веб-технологиями Майкрософт с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Sams Teach Yourself ASP.NET 2.0 в 24 часах. Он может быть доступен в mitchell@4GuysFromRolla.com. или через его блог, который можно найти по адресу http://ScottOnWriting.NET.
Особая благодарность
Эта серия учебников была рассмотрена многими полезными рецензентами. Ведущим рецензентом этого руководства был Деннис Паттерсон. Хотите просмотреть предстоящие статьи MSDN? Если да, опустите мне строку на mitchell@4GuysFromRolla.com.