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


Добавление кнопок и ответов на них к GridView (C#)

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

Загрузить PDF-файл

В этом руководстве мы рассмотрим, как добавить пользовательские кнопки как в шаблон, так и в поля элемента управления GridView или DetailsView. В частности, мы создадим интерфейс с FormView, который позволяет пользователю просматривать поставщиков.

Введение

Хотя многие сценарии создания отчетов предполагают доступ только для чтения к данным отчета, отчеты нередко включают возможность выполнять действия на основе отображаемых данных. Обычно это включало добавление веб-элемента управления Button, LinkButton или ImageButton с каждой записью, отображаемой в отчете, которая при щелчке вызывает обратную передачу и вызывает код на стороне сервера. Наиболее распространенным примером является изменение и удаление данных по записям. На самом деле, как мы видели, начиная с учебника Общие сведения о вставке, обновлении и удалении данных , редактирование и удаление настолько распространено, что элементы управления GridView, DetailsView и FormView могут поддерживать такие функции без необходимости написания одной строки кода.

Помимо кнопок "Изменить" и "Удалить", элементы управления GridView, DetailsView и FormView также могут включать кнопки, linkButtons или ImageButtons, которые при щелчке выполняют пользовательскую логику на стороне сервера. В этом руководстве мы рассмотрим, как добавить пользовательские кнопки как в шаблон, так и в поля элемента управления GridView или DetailsView. В частности, мы создадим интерфейс с FormView, который позволяет пользователю просматривать поставщиков. Для данного поставщика в FormView отображаются сведения о поставщике вместе с веб-элементом управления Кнопка, который при нажатии на нее помечает все связанные продукты как неподдерживаемые. Кроме того, в GridView перечислены продукты, предоставляемые выбранным поставщиком, с каждой строкой, содержащей кнопки повышения цены и цены со скидкой, которые при нажатии повышают или уменьшают значение продукта UnitPrice на 10 % (см. рис. 1).

FormView и GridView содержат кнопки, выполняющие пользовательские действия.

Рис. 1. И FormView, и GridView содержат кнопки, выполняющие пользовательские действия (щелкните для просмотра полноразмерного изображения)

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

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

  • Default.aspx
  • CustomButtons.aspx

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

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

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

Добавьте элемент управления SectionLevelTutorialListing.ascx в Default.aspx

Рис. 3. Добавление пользовательского SectionLevelTutorialListing.ascx элемента управления в Default.aspx (щелкните для просмотра полноразмерного изображения)

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

<siteMapNode
    title="Adding Custom Buttons"
    description="Samples of Reports that Include Buttons for Performing
                  Server-Side Actions"
    url="~/CustomButtons/Default.aspx">
    <siteMapNode
        title="Using ButtonFields and Buttons in Templates"
        description="Examines how to add custom Buttons, LinkButtons,
                      or ImageButtons as ButtonFields or within templates."
        url="~/CustomButtons/CustomButtons.aspx" />
</siteMapNode>

После обновления Web.sitemapпросмотрите веб-сайт учебников через браузер. Меню слева теперь содержит элементы для редактирования, вставки и удаления учебников.

Карта сайта теперь включает запись для руководства по настраиваемым кнопкам

Рис. 4. Карта сайта теперь включает запись для руководства по пользовательским кнопкам

Шаг 2. Добавление FormView, который Списки поставщиков

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

Начните с открытия страницы CustomButtons.aspx в папке CustomButtons . Добавьте FormView на страницу, перетащив его из панели элементов в Designer и присвоив свойству ID значение Suppliers. В смарт-теге FormView создайте объект ObjectDataSource с именем SuppliersDataSource.

Создание объекта ObjectDataSource с именем SuppliersDataSource

Рис. 5. Создание объекта ObjectDataSource с именем SuppliersDataSource (щелкните для просмотра полноразмерного изображения)

Настройте этот новый объект ObjectDataSource таким образом, чтобы он запрашивал метод SuppliersBLL класса GetSuppliers() (см. рис. 6). Так как этот FormView не предоставляет интерфейс для обновления сведений о поставщике, выберите параметр (Нет) в раскрывающемся списке на вкладке UPDATE.

Настройка источника данных для использования метода GetSuppliers() класса SuppliersBLL

Рис. 6. Настройка источника данных для использования SuppliersBLL метода класса GetSuppliers() (щелкните для просмотра полноразмерного изображения)

После настройки ObjectDataSource Visual Studio создаст InsertItemTemplate, EditItemTemplateи ItemTemplate для FormView. InsertItemTemplate Удалите и EditItemTemplate измените , ItemTemplate чтобы отображались только название и номер телефона поставщика. Наконец, включите поддержку разбиения по страницам для FormView, установив флажок Включить разбиение по страницам в смарт-теге (или установив для его AllowPaging свойства значение True). После этих изменений декларативная разметка страницы должна выглядеть примерно так:

<asp:FormView ID="Suppliers" runat="server" DataKeyNames="SupplierID"
    DataSourceID="SuppliersDataSource" EnableViewState="False" AllowPaging="True">
    <ItemTemplate>
        <h3>
            <asp:Label ID="CompanyName" runat="server"
                Text='<%# Bind("CompanyName") %>' />
        </h3>
        <b>Phone:</b>
        <asp:Label ID="PhoneLabel" runat="server" Text='<%# Bind("Phone") %>' />
    </ItemTemplate>
</asp:FormView>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetSuppliers" TypeName="SuppliersBLL">
</asp:ObjectDataSource>

На рисунке 7 показана страница CustomButtons.aspx при просмотре в браузере.

FormView Списки поля CompanyName и Phone от выбранного поставщика

Рис. 7. FormView Списки CompanyName поля и Phone из текущего выбранного поставщика (щелкните для просмотра полноразмерного изображения)

Шаг 3. Добавление элемента GridView, который Списки продуктов выбранного поставщика

Прежде чем добавить кнопку "Отменить все продукты" в шаблон FormView, давайте сначала добавим GridView под FormView, который содержит список продуктов, предоставляемых выбранным поставщиком. Для этого добавьте GridView на страницу, задайте для его ID свойства SuppliersProductsзначение и добавьте новый объект ObjectDataSource с именем SuppliersProductsDataSource.

Создание объекта ObjectDataSource с именем SuppliersProductsDataSource

Рис. 8. Создание объекта ObjectDataSource с именем SuppliersProductsDataSource (щелкните для просмотра полноразмерного изображения)

Настройте этот объект ObjectDataSource для использования метода класса GetProductsBySupplierID(supplierID) ProductsBLL (см. рис. 9). Хотя этот Элемент GridView позволяет скорректировать цену продукта, он не будет использовать встроенные функции редактирования или удаления из GridView. Таким образом, для раскрывающегося списка можно задать значение (Нет) для вкладок UPDATE, INSERT и DELETE объекта ObjectDataSource.

Настройка источника данных для использования метода GetProductsBySupplierID(supplierID) класса ProductsBLL

Рис. 9. Настройка источника данных для использования ProductsBLL метода класса GetProductsBySupplierID(supplierID) (щелкните для просмотра полноразмерного изображения)

GetProductsBySupplierID(supplierID) Так как метод принимает входной параметр, мастер ObjectDataSource запрашивает источник этого значения параметра. Чтобы передать SupplierID значение из FormView, задайте в раскрывающемся списке Источник параметров значение Control, а в раскрывающемся списке ControlID — значение Suppliers (идентификатор FormView, созданного на шаге 2).

Укажите, что параметр supplierID должен поступать из элемента управления

Рис. 10. Указание на supplierID то, что параметр должен поступать из Suppliers элемента управления FormView (щелкните для просмотра полноразмерного изображения)

После завершения работы мастера ObjectDataSource GridView будет содержать BoundField или CheckBoxField для каждого поля данных продукта. Давайте обрезаем его, чтобы отобразить только ProductName поля и UnitPrice BoundFields вместе с Discontinued CheckBoxField. Кроме того, давайте отформатируем UnitPrice BoundField таким образом, чтобы его текст был отформатирован в виде валюты. Декларативная разметка GridView и SuppliersProductsDataSource ObjectDataSource должна выглядеть примерно так:

<asp:GridView ID="SuppliersProducts" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="SuppliersProductsDataSource"
    EnableViewState="False" runat="server">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            SortExpression="UnitPrice" DataFormatString="{0:C}"
            HtmlEncode="False" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersProductsDataSource" runat="server"
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetProductsBySupplierID" TypeName="ProductsBLL">
    <SelectParameters>
        <asp:ControlParameter ControlID="Suppliers" Name="supplierID"
            PropertyName="SelectedValue" Type="Int32" />
    </SelectParameters>
</asp:ObjectDataSource>

На этом этапе в нашем руководстве отображается отчет master/details, позволяющий пользователю выбрать поставщика из FormView вверху и просмотреть продукты, предоставляемые этим поставщиком, через GridView в нижней части. На рисунке 11 показан снимок экрана этой страницы при выборе поставщика Tokyo Traders из FormView.

Продукты выбранного поставщика отображаются в GridView

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

Шаг 4. Создание методов DAL и BLL для прекращения поддержки всех продуктов для поставщика

Прежде чем добавить кнопку в FormView, которая при нажатии прекращает работу всех продуктов поставщика, сначала необходимо добавить метод в DAL и BLL, который выполняет это действие. В частности, этот метод будет называться DiscontinueAllProductsForSupplier(supplierID). При нажатии кнопки FormView мы вызовем этот метод на уровне бизнес-логики, передавая выбранный поставщик SupplierID; BLL вызовет соответствующий метод уровня доступа к данным, который выдаст UPDATE инструкцию для базы данных, которая прекращает работу с продуктами указанного поставщика.

Как и в предыдущих руководствах, мы будем использовать подход снизу вверх, начиная с создания метода DAL, затем метода BLL и, наконец, реализуем функциональные возможности на странице ASP.NET. Northwind.xsd Откройте typed DataSet в папке App_Code/DAL и добавьте в нее новый метод ProductsTableAdapter (щелкните правой ProductsTableAdapter кнопкой мыши и выберите Добавить запрос). При этом откроется мастер настройки запросов TableAdapter, который поможет нам добавить новый метод. Начните с указания, что наш метод DAL будет использовать нерегламентированную инструкцию SQL.

Создание метода DAL с помощью нерегламентированной инструкции SQL

Рис. 12. Создание метода DAL с помощью нерегламентированной инструкции SQL (щелкните для просмотра полноразмерного изображения)

Затем мастер предложит нам определить тип создаваемого запроса. DiscontinueAllProductsForSupplier(supplierID) Так как методу потребуется обновить таблицу Products базы данных, задав Discontinued для поля значение 1 для всех продуктов, предоставляемых указанным supplierID, необходимо создать запрос, обновляющий данные.

Выбор типа запроса UPDATE

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

На следующем экране мастера отображается существующая UPDATE инструкция TableAdapter, которая обновляет каждое из полей, определенных в Products таблице DataTable. Замените этот текст запроса следующей инструкцией:

UPDATE [Products] SET
   Discontinued = 1
WHERE SupplierID = @SupplierID

После ввода этого запроса и нажатия кнопки Далее на последнем экране мастера будет запрашиваться имя нового метода используйте DiscontinueAllProductsForSupplier. Завершите работу мастера, нажав кнопку Готово. После возвращения к Designer DataSet вы увидите ProductsTableAdapter новый метод в с именем DiscontinueAllProductsForSupplier(@SupplierID).

Назовите новый метод DAL DiscontinueAllProductsForSupplier

Рис. 14. Имя нового метода DiscontinueAllProductsForSupplier DAL (щелкните для просмотра полноразмерного изображения)

С помощью метода, созданного DiscontinueAllProductsForSupplier(supplierID) на уровне доступа к данным, наша следующая задача — создать DiscontinueAllProductsForSupplier(supplierID) метод на уровне бизнес-логики. Для этого откройте ProductsBLL файл класса и добавьте следующее:

public int DiscontinueAllProductsForSupplier(int supplierID)
{
    return Adapter.DiscontinueAllProductsForSupplier(supplierID);
}

Этот метод просто вызывает DiscontinueAllProductsForSupplier(supplierID) метод в DAL, передавая предоставленное supplierID значение параметра. Если существуют какие-либо бизнес-правила, которые разрешают отмену только продуктов поставщика при определенных обстоятельствах, эти правила должны быть реализованы здесь, в BLL.

Примечание

UpdateProduct В отличие от перегрузок в ProductsBLL классе, сигнатура DiscontinueAllProductsForSupplier(supplierID) метода не включает DataObjectMethodAttribute атрибут (<System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, Boolean)>). Это исключает DiscontinueAllProductsForSupplier(supplierID) использование метода из раскрывающегося списка мастера настройки источника данных ObjectDataSource на вкладке UPDATE. Я опустил этот атрибут, так как мы будем вызывать DiscontinueAllProductsForSupplier(supplierID) метод непосредственно из обработчика событий на странице ASP.NET.

Шаг 5. Добавление кнопки "Отменить все продукты" в FormView

DiscontinueAllProductsForSupplier(supplierID) После завершения метода в BLL и DAL последний шаг для добавления возможности прекращения использования всех продуктов для выбранного поставщика заключается в добавлении веб-элемента управления Button в FormView ItemTemplate. Давайте добавим такую кнопку под номером телефона поставщика с текстом кнопки Прекратить все продукты и значением IDDiscontinueAllProductsForSupplierсвойства . Этот веб-элемент управления "Кнопка" можно добавить через Designer, щелкнув ссылку Изменить шаблоны в смарт-теге FormView (см. рис. 15) или непосредственно с помощью декларативного синтаксиса.

Добавление веб-элемента управления

Рис. 15. Добавление веб-элемента управления "Кнопка "Отменить все продукты" в FormView ItemTemplate (щелкните для просмотра полноразмерного изображения)

При нажатии кнопки пользователем, посещающим страницу, происходит обратная связь и возникает событие FormViewItemCommand. Чтобы выполнить пользовательский код в ответ на нажатие кнопки, можно создать обработчик событий для этого события. Однако учтите, что ItemCommand событие возникает всякий раз, когда любой элемент управления Button, LinkButton или ImageButton web щелкается в FormView. Это означает, что при переходе пользователя с одной страницы на другую в FormView возникает событие, ItemCommand то же самое происходит при нажатии кнопки Создать, Изменить или Удалить в FormView, поддерживающем вставку, обновление или удаление.

ItemCommand Так как срабатывает независимо от того, какая кнопка нажата, в обработчике событий нам нужен способ определить, была ли нажата кнопка "Прекратить все продукты" или была ли это какая-то другая кнопка. Для этого можно задать для свойства веб-элемента управления CommandName Button некоторое идентифицируемое значение. При нажатии кнопки это CommandName значение передается в ItemCommand обработчик событий, что позволяет нам определить, была ли нажата кнопка "Прекратить все продукты". Задайте для свойства кнопки "Прекратить все продукты" CommandName значение DiscontinueProducts.

Наконец, давайте воспользуемся диалоговым окном подтверждения на стороне клиента, чтобы убедиться, что пользователь действительно хочет прекратить использование продуктов выбранного поставщика. Как мы видели в руководстве Добавление подтверждения Client-Side при удалении , это можно сделать с помощью немного JavaScript. В частности, присвойте свойству OnClientClick веб-элемента управления Кнопка значение return confirm('This will mark _all_ of this supplier\'s products as discontinued. Are you certain you want to do this?');

После внесения этих изменений декларативный синтаксис FormView должен выглядеть следующим образом:

<asp:FormView ID="Suppliers" runat="server" DataKeyNames="SupplierID"
    DataSourceID="SuppliersDataSource" EnableViewState="False"
    AllowPaging="True">
    <ItemTemplate>
        <h3><asp:Label ID="CompanyName" runat="server"
            Text='<%# Bind("CompanyName") %>'></asp:Label></h3>
        <b>Phone:</b>
        <asp:Label ID="PhoneLabel" runat="server" Text='<%# Bind("Phone") %>' />
        <br />
        <asp:Button ID="DiscontinueAllProductsForSupplier" runat="server"
            CommandName="DiscontinueProducts" Text="Discontinue All Products"
            OnClientClick="return confirm('This will mark _all_ of this supplier\'s
                products as discontinued. Are you certain you want to do this?');" />
    </ItemTemplate>
</asp:FormView>

Затем создайте обработчик событий для события FormView ItemCommand . В этом обработчике событий необходимо сначала определить, была ли нажата кнопка "Прекратить все продукты". Если это так, мы хотим создать экземпляр ProductsBLL класса и вызвать его DiscontinueAllProductsForSupplier(supplierID) метод, передавая SupplierID в выбранном FormView:

protected void Suppliers_ItemCommand(object sender, FormViewCommandEventArgs e)
{
    if (e.CommandName.CompareTo("DiscontinueProducts") == 0)
    {
        // The "Discontinue All Products" Button was clicked.
        // Invoke the ProductsBLL.DiscontinueAllProductsForSupplier(supplierID) method
        // First, get the SupplierID selected in the FormView
        int supplierID = (int)Suppliers.SelectedValue;
        // Next, create an instance of the ProductsBLL class
        ProductsBLL productInfo = new ProductsBLL();
        // Finally, invoke the DiscontinueAllProductsForSupplier(supplierID) method
        productInfo.DiscontinueAllProductsForSupplier(supplierID);
    }
}

Обратите внимание, что доступ к объекту SupplierID текущего выбранного поставщика в FormView можно получить с помощью свойства FormViewSelectedValue. Свойство SelectedValue возвращает первое значение ключа данных для записи, отображаемой в FormView. Свойство FormViewDataKeyNames, указывающее поля данных, из которых извлекаются значения ключа данных, было автоматически установлено SupplierID в Visual Studio при привязке ObjectDataSource к FormView на шаге 2.

Создав ItemCommand обработчик событий, проверьте страницу. Перейдите к поставщику Quesos 'Las Cabras' (это пятый поставщик в FormView для меня). Этот поставщик предоставляет два продукта, Queso Cabrales и Queso Manchego La Pastora, оба из которых не прекращены.

Представьте, что Коперива де Кесос "Лас Кабрас" вышел из бизнеса и, следовательно, его продукты должны быть прекращены. Нажмите кнопку Прекратить все продукты. Откроется диалоговое окно подтверждения на стороне клиента (см. рис. 16).

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

Рис. 16. Кооперативная работа Quesos Las Cabras Поставляет два активных продукта (щелкните для просмотра полноразмерного изображения)

Если нажать кнопку ОК в диалоговом окне подтверждения на стороне клиента, отправка формы продолжится, что вызовет обратную передачу, в которой срабатывает событие FormView ItemCommand . Созданный обработчик событий будет затем выполняться, вызывая DiscontinueAllProductsForSupplier(supplierID) метод и отменяя работу продуктов Queso Cabrales и Queso Manchego La Pastora.

Если вы отключили состояние представления GridView, GridView выполняет отскок к базовому хранилищу данных при каждой обратной отправке и, следовательно, будет немедленно обновлен, чтобы отразить, что эти два продукта теперь не поддерживаются (см. рис. 17). Однако если состояние представления в GridView не отключено, после внесения этого изменения потребуется вручную повторно привязать данные к GridView. Для этого просто вызовите метод GridView DataBind() сразу после вызова DiscontinueAllProductsForSupplier(supplierID) метода .

После нажатия кнопки

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

Шаг 6. Создание перегрузки UpdateProduct на уровне бизнес-логики для корректировки цены продукта

Как и в случае с кнопкой "Отменить все продукты" в FormView, чтобы добавить кнопки для увеличения и уменьшения цены на продукт в GridView, необходимо сначала добавить соответствующие методы уровня доступа к данным и уровня бизнес-логики. Так как у нас уже есть метод, который обновляет одну строку продукта в DAL, мы можем предоставить такую функциональность, создав новую перегрузку UpdateProduct для метода в BLL.

Наши прошлые UpdateProduct перегрузки приняли некоторое сочетание полей продукта в качестве скалярных входных значений, а затем обновили только эти поля для указанного продукта. Для этой перегрузки мы немного изменимся от этого стандарта и вместо этого передадим в продукте ProductID и процент, на который нужно настроить UnitPrice (в отличие от передачи нового, скорректированного UnitPrice самого). Такой подход упростит код, который необходимо написать в классе кода программной части страницы ASP.NET, так как нам не нужно беспокоиться об определении текущего продукта UnitPrice.

Перегрузка UpdateProduct для этого руководства показана ниже:

public bool UpdateProduct(decimal unitPriceAdjustmentPercentage, int productID)
{
    Northwind.ProductsDataTable products = Adapter.GetProductByProductID(productID);
    if (products.Count == 0)
        // no matching record found, return false
        return false;
    Northwind.ProductsRow product = products[0];
    // Adjust the UnitPrice by the specified percentage (if it's not NULL)
    if (!product.IsUnitPriceNull())
        product.UnitPrice *= unitPriceAdjustmentPercentage;
    // Update the product record
    int rowsAffected = Adapter.Update(product);
    // Return true if precisely one row was updated, otherwise false
    return rowsAffected == 1;
}

Эта перегрузка получает сведения о указанном продукте с помощью метода DAL GetProductByProductID(productID) . Затем проверяется, присвоено UnitPrice ли продукту значение базы данных NULL . Если это так, цена остается без изменения. Однако если имеется значение, отличноеNULLUnitPrice от значения, метод обновляет продукт UnitPrice на указанный процент (unitPriceAdjustmentPercent).

Шаг 7. Добавление кнопок увеличения и уменьшения в GridView

GridView (и DetailsView) состоят из коллекции полей. В дополнение к BoundFields, CheckBoxFields и TemplateFields, ASP.NET включает ButtonField, который, как следует из его названия, отрисовывается в виде столбца с Button, LinkButton или ImageButton для каждой строки. Как и в FormView, нажатие любой кнопки на страницах GridView, кнопок "Изменить" или "Удалить", кнопок сортировки и т. д. вызывает обратную передачу и вызывает событие GridViewRowCommand.

ButtonField имеет CommandName свойство , которое присваивает указанное значение каждому свойству Button CommandName . Как и в Случае с FormView, CommandName значение используется обработчиком RowCommand событий, чтобы определить, какая кнопка была нажата.

Давайте добавим два новых ButtonFields в GridView: один с кнопкой с текстом Price +10%, а другой с текстом Цена -10%. Чтобы добавить эти ButtonFields, щелкните ссылку Изменить столбцы в смарт-теге GridView, выберите тип поля ButtonField в списке в левом верхнем углу и нажмите кнопку Добавить.

Добавление двух buttonfields в GridView

Рис. 18. Добавление двух buttonfields в GridView

Переместите два ButtonFields, чтобы они отображались как первые два поля GridView. Затем задайте для Text свойств этих двух ButtonFields значения Price +10% и Price -10%, а CommandName свойствам — Значение IncreasePrice и DecreasePrice соответственно. По умолчанию ButtonField отображает свой столбец кнопок как LinkButtons. Однако это можно изменить с помощью свойства ButtonFieldButtonType. Давайте отрисуем эти два ButtonField в виде обычных кнопок. Поэтому присвойте свойству ButtonType значение Button. На рисунке 19 показано диалоговое окно Поля после внесения этих изменений; после этого — декларативная разметка GridView.

Настройка свойств ButtonFields Text, CommandName и ButtonType

Рис. 19. Настройка свойств ButtonFields Text, CommandNameи ButtonType

<asp:GridView ID="SuppliersProducts" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="SuppliersProductsDataSource"
    EnableViewState="False">
    <Columns>
        <asp:ButtonField ButtonType="Button" CommandName="IncreasePrice"
            Text="Price +10%" />
        <asp:ButtonField ButtonType="Button" CommandName="DecreasePrice"
            Text="Price -10%" />
        <asp:BoundField DataField="ProductName" HeaderText="Product"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            SortExpression="UnitPrice" DataFormatString="{0:C}"
            HtmlEncode="False" />
        <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
            SortExpression="Discontinued" />
    </Columns>
</asp:GridView>

После создания этих ButtonFields последним шагом является создание обработчика событий для события GridView RowCommand . Этот обработчик событий, если был активирован из-за нажатия кнопки Цена +10% или Цена -10%, должен определить ProductID для строки, кнопка которой была нажатаUpdateProduct, а затем вызвать ProductsBLL метод класса, передав соответствующую UnitPrice корректировку в процентах вместе с ProductID. Следующие задачи выполняются в следующем коде:

protected void SuppliersProducts_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName.CompareTo("IncreasePrice") == 0 ||
        e.CommandName.CompareTo("DecreasePrice") == 0)
    {
        // The Increase Price or Decrease Price Button has been clicked
        // Determine the ID of the product whose price was adjusted
        int productID =
            (int)SuppliersProducts.DataKeys[Convert.ToInt32(e.CommandArgument)].Value;
        // Determine how much to adjust the price
        decimal percentageAdjust;
        if (e.CommandName.CompareTo("IncreasePrice") == 0)
            percentageAdjust = 1.1M;
        else
            percentageAdjust = 0.9M;

        // Adjust the price
        ProductsBLL productInfo = new ProductsBLL();
        productInfo.UpdateProduct(percentageAdjust, productID);
    }
}

Чтобы определить ProductID для строки, для которой была нажата кнопка Цена +10% или Цена -10%, необходимо обратиться к коллекции GridView DataKeys . Эта коллекция содержит значения полей, указанных в свойстве DataKeyNames для каждой строки GridView. Так как при привязке ObjectDataSource к GridView свойству GridView DataKeyNames при привязке ObjectDataSource к GridView задано значение ProductID, DataKeys(rowIndex).Value предоставляет ProductID для указанного rowIndex.

ButtonField автоматически передает значение rowIndex строки, кнопка которой была нажата e.CommandArgument через параметр . Поэтому, чтобы определить ProductID для строки, для которой была нажата кнопка Цена +10% или Цена -10%, используется: Convert.ToInt32(SuppliersProducts.DataKeys(Convert.ToInt32(e.CommandArgument)).Value).

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

На рисунке 20 показана страница при просмотре продуктов, предоставляемых homestead бабушки Келли. На рисунке 21 показаны результаты после того, как кнопка Цена +10% была дважды нажата для бабушки Boysenberry Spread и цена -10% кнопка один раз для Нортвудса Cranberry Sauce.

GridView включает кнопки

Рис. 20. GridView включает кнопки "Цена +10% " и Цена -10 % (щелкните для просмотра полноразмерного изображения)

Цены на первый и третий продукт обновлены с помощью кнопок Цена +10% и Цена -10%

Рис. 21. Цены на первый и третий продукт обновлены с помощью кнопок Цена +10% и Цена -10% (Нажмите для просмотра полноразмерного изображения)

Примечание

GridView (и DetailsView) также могут содержать кнопки, linkButtons или ImageButtons, добавленные в их TemplateField. Как и в случае с BoundField, эти кнопки при нажатии вызывают обратную передачу, вызывая событие GridView RowCommand . Однако при добавлении кнопок в TemplateField для элемента Button CommandArgument не устанавливается индекс строки автоматически, как при использовании ButtonFields. Если необходимо определить индекс строки кнопки, которая была нажата в RowCommand обработчике событий, необходимо вручную задать свойство Button в декларативном CommandArgument синтаксисе в TemplateField, используя следующий код:
<asp:Button runat="server" ... CommandArgument='<%# ((GridViewRow) Container).RowIndex %>'.

Сводка

Элементы управления GridView, DetailsView и FormView могут включать button, LinkButtons или ImageButtons. Такие кнопки при нажатии вызывают обратную передачу ItemCommand и вызывают событие в элементах управления FormView и DetailsView и RowCommand событие в GridView. Эти веб-элементы управления данными имеют встроенные функции для обработки распространенных действий, связанных с командами, таких как удаление или изменение записей. Однако мы также можем использовать кнопки, которые при нажатии отвечают на выполнение собственного пользовательского кода.

Для этого необходимо создать обработчик событий для ItemCommand события или RowCommand . В этом обработчике событий сначала проверка входящее CommandName значение, чтобы определить, какая кнопка была нажата, а затем выполнить соответствующее настраиваемое действие. В этом руководстве мы узнали, как использовать кнопки и ButtonFields, чтобы отменить все продукты для указанного поставщика или увеличить или уменьшить цену на определенный продукт на 10 %.

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

Об авторе

Скотт Митчелл( Scott Mitchell), автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с веб-технологиями Майкрософт с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Sams Teach Yourself ASP.NET 2.0 в 24 часах. Он может быть доступен в mitchell@4GuysFromRolla.com. или через его блог, который можно найти по адресу http://ScottOnWriting.NET.