Настраиваемые кнопки в элементах управления DataList и Repeater (C#)
В этом руководстве мы создадим интерфейс, который использует 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. Добавление списка категорий
Для работы с этим руководством необходимо создать ретранслятор, который выводит список всех категорий, а также элемент Show Products LinkButton, который при щелчке отображает связанные продукты категории в маркированный список. Сначала создадим простой повторитель, который перечисляет категории в системе. Начните с открытия страницы CustomButtons.aspx
в папке CustomButtonsDataListRepeater
. Перетащите repeater из панели элементов на Designer и задайте для его ID
свойства значение Categories
. Затем создайте новый элемент управления источником данных из смарт-тега Repeater. В частности, создайте новый элемент управления ObjectDataSource с именем CategoriesDataSource
, который выбирает свои данные из CategoriesBLL
метода класса .GetCategories()
Рис. 5. Настройка ObjectDataSource для использования CategoriesBLL
метода Classs 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 может также вызвать другое, более конкретное событие, если свойству buttons присвоена 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. Отображение продуктов выбранных категорий в маркированных списках
Выбранные продукты категории можно отобразить в ретрансляторе ItemTemplate
с помощью любого количества элементов управления. Можно добавить еще один вложенный повторитель, DataList, DropDownList, GridView и т. д. Так как мы хотим отобразить продукты в виде маркированного списка, мы будем использовать элемент управления BulletedList. Вернувшись к CustomButtons.aspx
декларативной разметке страницы, добавьте элемент управления ItemTemplate
BulletedList после элемента управления 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 void Categories_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "ShowProducts")
{
// Determine the CategoryID
int categoryID = Convert.ToInt32(e.CommandArgument);
// Get the associated products from the ProudctsBLL and bind
// them to the BulletedList
BulletedList products =
(BulletedList)e.Item.FindControl("ProductsInCategory");
ProductsBLL productsAPI = new ProductsBLL();
products.DataSource =
productsAPI.GetProductsByCategoryID(categoryID);
products.DataBind());
}
}
Перед выполнением какого-либо действия в обработчике 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 могут включать любое количество кнопок, linkButton и 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.