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


Настраиваемые кнопки в компонентах DataList и Repeater (C#)

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

Скачивание PDF

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

Введение

В последних семнадцати руководствах DataList и Repeater мы создали как примеры только для чтения, так и примеры для редактирования и удаления. Чтобы упростить функции редактирования и удаления в DataList, мы добавили кнопки в ItemTemplate внутри DataList, которые при нажатии инициируют обратную передачу и вызывают событие DataList, соответствующее свойству кнопки CommandName. Например, добавление кнопки в ItemTemplate со значением свойства Edit приводит к тому, что DataList срабатывает CommandName при обратной отправке; кнопка со свойством Delete вызывает EditCommand.

Помимо кнопок "Изменить" и "Удалить", элементы управления DataList и Repeater также могут включать кнопки, такие как "кнопки-ссылки" или "кнопки-изображения", которые при щелчке выполняют определенную пользовательскую логику на стороне сервера. В этом руководстве мы создадим интерфейс, использующий повторитель для перечисления категорий в системе. Для каждой категории повторитель будет включать кнопку, чтобы с помощью элемента управления BulletedList отобразить связанные продукты (см. рис. 1).

Щелкнув ссылку

Рис. 1. Щелкнув ссылку "Показать продукты", отображаются продукты категории в маркированном списке (щелкните, чтобы просмотреть изображение полного размера)

Шаг 1. Добавление веб-страниц учебника по пользовательской кнопке

Прежде чем мы рассмотрим, как добавить пользовательскую кнопку, давайте сначала рассмотрим, как создать страницы ASP.NET в нашем проекте веб-сайта, который нам потребуется для этого руководства. Сначала добавьте новую папку с именем CustomButtonsDataListRepeater. Затем добавьте в нее следующие две ASP.NET страницы, чтобы связать каждую страницу с главной страницей Site.master :

  • Default.aspx
  • CustomButtons.aspx

Добавление страниц ASP.NET для пользовательских учебников Buttons-Related

Рис. 2. Добавление страниц ASP.NET для пользовательских руководств Buttons-Related

Как и в других папках, Default.aspx в папке CustomButtonsDataListRepeater перечислены учебные материалы в соответствующем разделе. Помните, что элемент SectionLevelTutorialListing.ascx управления пользователем предоставляет эту функцию. Добавьте этот управляющий элемент Default.aspx, перетащив его из обозревателя решений в окно конструктора страницы.

Добавьте элемент управления 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 из панели инструментов на дизайнер и установите свойство ID в Categories. Затем создайте новый элемент управления источником данных из смарт-тега Repeater. В частности, создайте элемент управления ObjectDataSource с именем CategoriesDataSource , который выбирает данные из CategoriesBLL метода класса GetCategories() .

Настройте ObjectDataSource для использования метода GetCategories() класса CategoriesBLL

Рис. 5. Настройка ObjectDataSource для использования CategoriesBLL метода класса GetCategories() (щелкните, чтобы просмотреть изображение полного размера)

В отличие от элемента управления DataList, для которого Visual Studio создает значение по умолчанию ItemTemplate на основе источника данных, шаблоны повторителя должны быть определены вручную. Кроме того, шаблоны Repeater должны быть созданы и изменены объявительно (т. е. в смарт-теге Repeater нет параметра "Edit Templates").

Нажмите вкладку «Источник» в левом нижнем углу и добавьте 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 показана страница при просмотре через браузер. Отображается имя и описание каждой категории. Кнопка "Показать продукты" при нажатии вызывает обратную отправку данных, но не выполняет никаких действий.

Отображается имя и описание каждой категории, а также show Products LinkButton

Рис. 6. Отображается имя и описание каждой категории вместе с элементом Show Products LinkButton (щелкните, чтобы просмотреть изображение полного размера)

Шаг 3: Выполнение логики Server-Side при нажатии на кнопку "Показать продукты" LinkButton

Каждый раз при нажатии кнопки, LinkButton или ImageButton в шаблоне объекта DataList или Repeater происходит обратная передача, и событие DataList или Repeater ItemCommand инициируется. В дополнение к ItemCommand событию элемент управления DataList также может вызвать другое, более конкретное событие, если свойству кнопки CommandName присвоено одно из зарезервированных строк (Delete, Edit, Cancel, Update или Select), однако ItemCommand событие всегда запускается.

При щелчке кнопки в элементе управления DataList или Repeater часто необходимо передать информацию о том, какая кнопка была нажата (в случае, если в элементе управления может быть несколько кнопок, например, кнопки 'Изменить' и 'Удалить'), а также, возможно, некоторые дополнительные сведения (например, значение первичного ключа элемента, кнопка которого была нажата). Кнопка, 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 кнопки.

Создайте обработчик событий для события Повторителя ItemCommand и запишите второй параметр, переданный в обработчик событий (с именем e). Этот второй параметр имеет тип RepeaterCommandEventArgs и имеет следующие четыре свойства:

  • CommandArgumentЗначение свойства кнопки нажатия CommandArgument
  • CommandNameзначение свойства кнопки CommandName
  • CommandSource Ссылка на элемент управления кнопкой, на который было выполнено нажатие
  • Item Ссылка на RepeaterItem, содержащую кнопку, которая была нажата; каждая запись, привязанная к повторителю, представлена как RepeaterItem

Так как выбранная категория CategoryID передается через CommandArgument свойство, мы можем получить набор продуктов, связанных с выбранной категорией, в обработчике событий ItemCommand. Затем эти продукты можно привязать к контроллеру BulletedList в ItemTemplate (который еще не добавлен). Все, что остается, — добавить Маркированный список, ссылаться на него в ItemCommand обработчике событий и привязать к нему набор продуктов для выбранной категории, которую мы рассмотрим на шаге 4.

Замечание

Обработчик событий DataList ItemCommand передает объект типа DataListCommandEventArgs, который предлагает те же четыре свойства, что и RepeaterCommandEventArgs класс.

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

Продукты выбранной категории можно отобразить в повторяющемся элементе ItemTemplate, используя любое количество элементов управления. Мы могли бы добавить еще один вложенный повторитель, DataList, DropDownList, GridView и так далее. Так как мы хотим отобразить продукты в виде маркированного списка, мы будем использовать элемент управления BulletedList. Вернитесь к декларативной разметке страницы CustomButtons.aspx, добавьте элемент управления BulletedList после элемента управления Show Products LinkButton в ItemTemplate. Установите для маркерированных списков ID значение ProductsInCategory. Маркерированный список отображает значение поля данных, указанного через свойство 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, повторитель не имеет DataKeys свойства. Вместо этого мы должны использовать альтернативный подход для предоставления значения первичного ключа, например, через свойство кнопки CommandArgument или путем назначения значения первичного ключа скрытому веб-элементу управления Label в шаблоне и считывания его значения обратно в обработчике событий ItemCommand с помощью e.Item.FindControl("LabelID").

После завершения ItemCommand обработчика событий, уделите некоторое время, чтобы протестировать эту страницу в браузере. Как показано на рисунке 7, щелчок по ссылке "Показать товары" вызывает обратный вызов и отображает товары для выбранной категории в маркированном списке. Кроме того, обратите внимание, что эта информация о продукте остается, даже если щелкнуть ссылки на другие категории "Показать продукты".

Замечание

Если вы хотите изменить поведение этого отчета, таким образом, чтобы в одно время отображались только продукты одной категории, просто задайте для свойства элемента управления EnableViewState BulletedList значение False.

Маркированный список используется для отображения продуктов выбранной категории

Рис. 7. Маркированный список используется для отображения продуктов выбранной категории (щелкните, чтобы просмотреть изображение полного размера)

Сводка

Элементы управления DataList и Repeater могут включать любое количество кнопок, LinkButtons или ImageButtons в их шаблонах. Такие кнопки при щелчке обратно вызывают и инициируют событие ItemCommand. Чтобы связать пользовательское действие на стороне сервера с нажатием кнопки, создайте обработчик событий для ItemCommand события. В этом обработчике событий сначала проверьте входящее CommandName значение, чтобы определить, какая кнопка была нажата. Дополнительные сведения можно предоставить с помощью свойства кнопки CommandArgument .

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

Сведения о авторе

Скотт Митчелл, автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с технологиями Microsoft Web с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Sams Teach Yourself ASP.NET 2.0 за 24 часа. С ним можно связаться по адресу mitchell@4GuysFromRolla.com.

Особое спасибо кому

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