Отображение сводной информации в нижнем колонтитуле элемента управления GridView (VB)

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

Скачивание PDF

Сводная информация часто отображается в нижней части отчета в строке сводки. Элемент управления GridView может включать строку нижнего колонтитула, в ячейки которой можно программно внедрять суммарные данные. В этом руководстве мы рассмотрим, как отображать агрегированные данные в этой строке нижнего колонтитула.

Введение

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

Эта задача представляет нам три задачи:

  1. Настройка GridView для отображения строки футера
  2. Определение суммарных данных; То есть как вычислить среднюю цену или общую сумму единиц акций?
  3. Вставка сводных данных в соответствующие ячейки строки нижнего колонтитула

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

Сводная информация отображается в строке нижнего колонтитула GridView

Рис. 1. Сводная информация отображается в строке нижнего колонтитула GridView (щелкните, чтобы просмотреть изображение полного размера)

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

Шаг 1. Добавление раскрывающегося списка категорий и таблицы продуктов GridView

Прежде чем приступить к добавлению сводной информации в нижний колонтитул GridView, сначала сначала создадим главный или подробный отчет. Завершив этот первый шаг, мы рассмотрим, как включить сводные данные.

Начните с открытия SummaryDataInFooter.aspx страницы в папке CustomFormatting . Добавьте элемент управления DropDownList и задайте его ID на Categories. Затем щелкните ссылку "Выбор источника данных" из смарт-тега DropDownList и выберите новый объект ObjectDataSource с именем CategoriesDataSource , который вызывает CategoriesBLL метод класса GetCategories() .

Добавление нового объекта ObjectDataSource с именем CategoriesDataSource

Рис. 2. Добавление нового имени ObjectDataSource (CategoriesDataSourceщелкните, чтобы просмотреть изображение полного размера)

Заставьте ObjectDataSource вызвать метод GetCategories() класса CategoriesBLL

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

После настройки ObjectDataSource мастер возвращает нас к мастеру конфигурации источника данных DropDownList, где необходимо указать, какое значение поля данных должно отображаться и какое должно соответствовать значению DropDownList ListItem. Отобразите поле CategoryName и используйте CategoryID в качестве значения.

Используйте поля CategoryName и CategoryID в качестве текста и значения для ListItems соответственно

Рис. 4. Используйте поля CategoryName и CategoryID в качестве Text и Value соответственно для ListItem, (щелкните, чтобы просмотреть изображение в полном размере)

На этом этапе у нас есть выпадающий список (Categories), который перечисляет категории в системе. Теперь необходимо добавить GridView, который перечисляет те продукты, которые относятся к выбранной категории. Прежде чем мы сделаем это, обратите внимание на флажок Enable AutoPostBack в смарт-теге DropDownList. Как было рассмотрено в руководстве по мастер/детализации с фильтрацией через раскрывающийся список, при изменении значения DropDownList страница будет отправляться обратно, если установить свойство DropDownList на AutoPostBack. Это приведет к обновлению GridView, показывающее эти продукты для только что выбранной категории. AutoPostBack Если для свойства задано значение False (по умолчанию), изменение категории не приведет к обратной отправке и поэтому не будет обновлять перечисленные продукты.

Установите флажок Enable AutoPostBack в смарт-теге DropDownList

Рис. 5. Установите флажок "Включить autoPostBack" в смарт-теге DropDownList (щелкните, чтобы просмотреть изображение полного размера)

Добавьте элемент управления GridView на страницу, чтобы отобразить продукты для выбранной категории. Задайте для GridView IDProductsInCategory значение и привязать его к новому объекту ObjectDataSource с именем ProductsInCategoryDataSource.

Добавление нового объекта ObjectDataSource с именем ProductsInCategoryDataSource

Рис. 6. Добавление нового объекта ObjectDataSource С именем ProductsInCategoryDataSource (щелкните, чтобы просмотреть изображение полного размера)

Настройте ObjectDataSource таким образом, чтобы он запускал метод класса GetProductsByCategoryID(categoryID)ProductsBLL.

Пусть ObjectDataSource вызовет метод GetProductsByCategoryID(categoryID)

Рис. 7. Вызов GetProductsByCategoryID(categoryID) метода ObjectDataSource (щелкните, чтобы просмотреть изображение полного размера)

Поскольку метод принимает входной параметр, на последнем шаге мастера GetProductsByCategoryID(categoryID) можно указать источник значения этого параметра. Чтобы отобразить эти продукты из выбранной категории, необходимо извлечь параметр из Categories DropDownList.

Снимок экрана: окно

Рис. 8. Получение categoryID значения параметра из раскрывающегося списка выбранных категорий (щелкните, чтобы просмотреть изображение полного размера)

После завершения работы мастера настроек GridView будет иметь BoundField для каждого свойства продукта. Давайте очистим эти BoundFields таким образом, чтобы отображались только ProductName, UnitPrice, UnitsInStock, и UnitsOnOrder BoundFields. Вы можете добавить все параметры уровня поля в оставшиеся поля BoundFields (например, форматирование UnitPrice в виде валюты). После внесения этих изменений декларативная разметка GridView должна выглядеть следующим образом:

<asp:GridView ID="ProductsInCategory" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ProductsInCategoryDataSource"
    EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="ProductName" HeaderText="Product"
          SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}"
          HeaderText="Price"
            HtmlEncode="False" SortExpression="UnitPrice">
            <ItemStyle HorizontalAlign="Right" />
        </asp:BoundField>
        <asp:BoundField DataField="UnitsInStock"
          HeaderText="Units In Stock" SortExpression="UnitsInStock">
            <ItemStyle HorizontalAlign="Right" />
        </asp:BoundField>
        <asp:BoundField DataField="UnitsOnOrder"
          HeaderText="Units On Order" SortExpression="UnitsOnOrder">
            <ItemStyle HorizontalAlign="Right" />
        </asp:BoundField>
    </Columns>
</asp:GridView>

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

Снимок экрана: отчет GridView для тех продуктов, которые относятся к категории

Рис. 9. Получение categoryID значения параметра из раскрывающегося списка выбранных категорий (щелкните, чтобы просмотреть изображение полного размера)

Элемент управления GridView может отображать как строку заголовка, так и строку нижнего колонтитула. Эти строки отображаются в зависимости от значений свойств ShowHeader и ShowFooter соответственно, при этом ShowHeader по умолчанию равняется True, а ShowFooter - до False. Чтобы включить нижний колонтитул в GridView, просто установите значение свойства ShowFooter в True.

Задайте для свойства ShowFooter GridView значение True

Рис. 10. Задайте для свойства ShowFooter GridView True значение (щелкните, чтобы просмотреть изображение полного размера)

Строка нижнего колонтитула содержит ячейку для каждого из полей, определенных в GridView; однако эти ячейки пусты по умолчанию. Ознакомьтесь с нашим прогрессом в браузере. Теперь для свойства ShowFooter задано значение True, и GridView содержит пустую строку нижнего колонтитула.

GridView теперь включает строку нижнего колонтитула

Рис. 11. GridView теперь включает строку нижнего колонтитула (нажмите, чтобы открыть изображение в полном размере)

Строка в нижней части на рис. 11 не выделяется, так как она имеет белый фон. Давайте создадим FooterStyle класс CSS в Styles.css, который задает темно-красный фон, и затем настройте файл GridView.skin Skin в теме DataWebControls, чтобы этот класс CSS назначался свойству FooterStyle элемента GridView CssClass. Если вам нужно освежить свои знания о скинах и темах, обратитесь к руководству по отображению данных с помощью ObjectDataSource.

Начните с добавления следующего класса CSS в Styles.css:

.FooterStyle
{
    background-color: #a33;
    color: White;
    text-align: right;
}

Класс FooterStyle CSS схож по стилю с классом HeaderStyle, однако цвет фона HeaderStyle немного темнее, а текст отображается жирным шрифтом. Кроме того, текст в нижнем колонтитуле выровнен по правому краю, а текст в верхнем колонтитуле выровнен по центру.

Затем, чтобы связать этот класс CSS с каждым нижним колонтитулом GridView, откройте файл GridView.skin в теме DataWebControls и задайте свойство FooterStyleCssClass. После этого добавления разметка файла должна выглядеть следующим образом:

<asp:GridView runat="server" CssClass="DataWebControlStyle">
   <AlternatingRowStyle CssClass="AlternatingRowStyle" />
   <RowStyle CssClass="RowStyle" />
   <HeaderStyle CssClass="HeaderStyle" />
   <FooterStyle CssClass="FooterStyle" />
   <SelectedRowStyle CssClass="SelectedRowStyle" />
</asp:GridView>

Как показано на снимке экрана ниже, это изменение делает нижний колонтитул более четким.

Снимок экрана, демонстрирующий сводные данные в нижней строке GridView, оформленные с новым цветом фона.

Рис. 12. Строка нижнего колонтитула GridView теперь имеет красный цвет фона (щелкните, чтобы просмотреть изображение полного размера)

Шаг 3. Вычисление сводных данных

При показе подвала GridView следующей задачей является подсчёт итоговых данных. Существует два способа вычисления этой статистической информации:

  1. С помощью SQL-запроса можно выполнить дополнительный запрос к базе данных, чтобы вычислить сводные данные для определенной категории. SQL включает ряд агрегатных функций вместе с GROUP BY предложением, чтобы указать данные, над которыми должны быть обобщены данные. Следующий SQL-запрос возвратит необходимые сведения:

    SELECT CategoryID, AVG(UnitPrice), SUM(UnitsInStock),
    SUM(UnitsOnOrder)
    FROM Products
    WHERE CategoryID = categoryID
    GROUP BY CategoryID
    

    Конечно, вы не хотите выдавать этот запрос непосредственно со страницы SummaryDataInFooter.aspx, а вместо этого создать метод в ProductsTableAdapter и ProductsBLL.

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

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

RowDataBound Создайте обработчик событий для GridView, выбрав GridView в Конструкторе, щелкнув значок молнии в окне свойств и дважды щелкнув на событии RowDataBound. Кроме того, вы можете выбрать GridView и его событие RowDataBound из раскрывающихся списков в верхней части файла кода класса ASP.NET. При этом будет создан новый обработчик событий с именем ProductsInCategory_RowDataBound в классе кода програмного модуля страницы SummaryDataInFooter.aspx.

Protected Sub ProductsInCategory_RowDataBound _
    (sender As Object, e As GridViewRowEventArgs) _
        Handles ProductsInCategory.RowDataBound
End Sub

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

  • _totalUnitPrice, типа Decimal
  • _totalNonNullUnitPriceCount, тип Integer
  • _totalUnitsInStock, тип Integer
  • _totalUnitsOnOrder, тип Integer

Затем напишите код, чтобы увеличить эти три переменные для каждой строки данных, обнаруженной в обработчике RowDataBound событий.

Dim _totalUnitPrice As Decimal = 0
Dim _totalNonNullUnitPriceCount As Integer = 0
Dim _totalUnitsInStock As Integer = 0
Dim _totalUnitsOnOrder As Integer = 0
Protected Sub ProductsInCategory_RowDataBound _
    (sender As Object, e As GridViewRowEventArgs) _
        Handles ProductsInCategory.RowDataBound
    If e.Row.RowType = DataControlRowType.DataRow Then
        Dim product As Northwind.ProductsRow = _
            CType(CType(e.Row.DataItem, DataRowView).Row, Northwind.ProductsRow)
        If Not product.IsUnitPriceNull() Then
            _totalUnitPrice += product.UnitPrice
            _totalNonNullUnitPriceCount += 1
        End If
        If Not product.IsUnitsInStockNull() Then
            _totalUnitsInStock += product.UnitsInStock
        End If
        If Not product.IsUnitsOnOrderNull() Then
            _totalUnitsOnOrder += product.UnitsOnOrder
        End If
    ElseIf e.Row.RowType = DataControlRowType.Footer Then
        Dim avgUnitPrice As Decimal = _
            _totalUnitPrice / CType(_totalNonNullUnitPriceCount, Decimal)
        e.Row.Cells(1).Text = "Avg.: " & avgUnitPrice.ToString("c")
        e.Row.Cells(2).Text = "Total: " & _totalUnitsInStock.ToString()
        e.Row.Cells(3).Text = "Total: " & _totalUnitsOnOrder.ToString()
    End If
End Sub

Обработчик RowDataBound событий начинается с обеспечения того, что мы имеем дело с DataRow. После того как это установлено, экземпляр Northwind.ProductsRow, который только что был привязан к объекту GridViewRow, e.Row хранится в переменной product. Затем переменные текущей суммы увеличиваются на соответствующие значения текущего продукта (при условии, что они не содержат значения базы данных NULL). Мы отслеживаем как общую суммуUnitPrice, так и количество неNULLUnitPrice записей, так как средняя цена является частным этих двух чисел.

Сводные данные подводятся последним шагом, чтобы отобразить их в строке нижнего колонтитула GridView. Эта задача также может быть выполнена программным способом с помощью обработчика RowDataBound событий. Напоминаем, что обработчик событий RowDataBound срабатывает для каждой строки, привязанной к GridView, включая строку футера. Поэтому мы можем расширить обработчик событий для отображения данных в строке нижнего колонтитула с помощью следующего кода:

Protected Sub ProductsInCategory_RowDataBound _
    (sender As Object, e As GridViewRowEventArgs) _
        Handles ProductsInCategory.RowDataBound
    If e.Row.RowType = DataControlRowType.DataRow Then
      ... Increment the running totals ...
    ElseIf e.Row.RowType = DataControlRowType.Footer
      ... Display the summary data in the footer ...
    End If
End Sub

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

Чтобы отобразить текст в определенной ячейке нижнего колонтитула, используйте e.Row.Cells(index).Text = value, где Cells индексирование начинается с 0. Следующий код вычисляет среднюю цену (общую цену, деленную на количество товаров) и выводит их вместе с общим числом единиц на складе и единиц в заказе в соответствующих ячейках нижнего колонтитула GridView.

Protected Sub ProductsInCategory_RowDataBound _
    (sender As Object, e As GridViewRowEventArgs) _
        Handles ProductsInCategory.RowDataBound
    If e.Row.RowType = DataControlRowType.DataRow Then
      ... <i>Increment the running totals</i> ...
    ElseIf e.Row.RowType = DataControlRowType.Footer
      Dim avgUnitPrice As Decimal = _
        _totalUnitPrice / CType(_totalNonNullUnitPriceCount, Decimal)
      e.Row.Cells(1).Text = "Avg.: " & avgUnitPrice.ToString("c")
      e.Row.Cells(2).Text = "Total: " & _totalUnitsInStock.ToString()
      e.Row.Cells(3).Text = "Total: " & _totalUnitsOnOrder.ToString()
    End If
End Sub

На рисунке 13 показан отчет после добавления этого кода. Обратите внимание, что ToString("c") сводная информация о средней цене будет отформатирована как валюта.

Снимок экрана, показывающий сводные данные в строке нижнего колонтитула GridView, оформленной как валюта.

Рис. 13. Строка нижнего колонтитула GridView теперь имеет красный цвет фона (щелкните, чтобы просмотреть изображение полного размера)

Итоги

Отображение сводных данных является общим требованием к отчету, и элемент управления GridView упрощает включение таких сведений в строку нижнего колонтитула. Строка нижнего колонтитула отображается, когда свойство GridView ShowFooter задано True и может иметь текст в своих ячейках, заданный программно с помощью обработчика событий RowDataBound. Вычисление суммарных данных можно выполнить путем повторного запроса базы данных или с помощью кода в классе кода ASP.NET страницы для программного вычисления сводных данных.

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

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

Об авторе

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