Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Сводная информация часто отображается в нижней части отчета в строке сводки. Элемент управления GridView может включать строку нижнего колонтитула, в ячейки которой можно программно внедрять суммарные данные. В этом руководстве мы рассмотрим, как отображать агрегированные данные в этой строке нижнего колонтитула.
Введение
Помимо просмотра цен на продукты, единиц на складе, единиц в заказе и уровней повторного заказа, пользователь также может быть заинтересован в сводной информации, например, средней цене, общем количестве единиц на складе и т. д. Такие сводные сведения часто отображаются в нижней части отчета в строке сводки. Элемент управления GridView может включать строку нижнего колонтитула, в ячейки которой можно программно внедрять суммарные данные.
Эта задача представляет нам три задачи:
- Настройка GridView для отображения строки футера
- Определение суммарных данных; То есть как вычислить среднюю цену или общую сумму единиц акций?
- Вставка сводных данных в соответствующие ячейки строки нижнего колонтитула
В этом руководстве мы посмотрим, как преодолеть эти проблемы. В частности, мы создадим страницу, которая перечисляет категории в раскрывающемся списке с продуктами выбранной категории, отображаемыми в GridView. GridView будет включать в себя строку нижнего колонтитула, которая показывает среднюю цену и общее количество единиц на складе и в заказе для продуктов в этой категории.
Рис. 1. Сводная информация отображается в строке нижнего колонтитула GridView (щелкните, чтобы просмотреть изображение полного размера)
В этом руководстве для интерфейса "мастер/детали" категорий продуктов развиваются концепции, изложенные в предыдущем руководстве по фильтрации "мастер/детали" с помощью раскрывающегося списка. Если вы еще не работали с предыдущим руководством, сделайте это, прежде чем продолжить работу с этим.
Шаг 1. Добавление раскрывающегося списка категорий и таблицы продуктов GridView
Прежде чем приступить к добавлению сводной информации в нижний колонтитул GridView, сначала сначала создадим главный или подробный отчет. Завершив этот первый шаг, мы рассмотрим, как включить сводные данные.
Начните с открытия SummaryDataInFooter.aspx страницы в папке CustomFormatting . Добавьте элемент управления DropDownList и задайте его ID на Categories. Затем щелкните ссылку "Выбор источника данных" из смарт-тега DropDownList и выберите новый объект ObjectDataSource с именем CategoriesDataSource , который вызывает CategoriesBLL метод класса GetCategories() .
Рис. 2. Добавление нового имени ObjectDataSource (CategoriesDataSourceщелкните, чтобы просмотреть изображение полного размера)
Рис. 3. ObjectDataSource вызывает метод CategoriesBLL класса GetCategories() (щелкните, чтобы увидеть изображение в полном размере)
После настройки ObjectDataSource мастер возвращает нас к мастеру конфигурации источника данных DropDownList, где необходимо указать, какое значение поля данных должно отображаться и какое должно соответствовать значению DropDownList ListItem. Отобразите поле CategoryName и используйте CategoryID в качестве значения.
Рис. 4. Используйте поля CategoryName и CategoryID в качестве Text и Value соответственно для ListItem, (щелкните, чтобы просмотреть изображение в полном размере)
На этом этапе у нас есть выпадающий список (Categories), который перечисляет категории в системе. Теперь необходимо добавить GridView, который перечисляет те продукты, которые относятся к выбранной категории. Прежде чем мы сделаем это, обратите внимание на флажок Enable AutoPostBack в смарт-теге DropDownList. Как было рассмотрено в руководстве по мастер/детализации с фильтрацией через раскрывающийся список, при изменении значения DropDownList страница будет отправляться обратно, если установить свойство DropDownList на AutoPostBack. Это приведет к обновлению GridView, показывающее эти продукты для только что выбранной категории.
AutoPostBack Если для свойства задано значение False (по умолчанию), изменение категории не приведет к обратной отправке и поэтому не будет обновлять перечисленные продукты.
Рис. 5. Установите флажок "Включить autoPostBack" в смарт-теге DropDownList (щелкните, чтобы просмотреть изображение полного размера)
Добавьте элемент управления GridView на страницу, чтобы отобразить продукты для выбранной категории. Задайте для GridView IDProductsInCategory значение и привязать его к новому объекту ObjectDataSource с именем ProductsInCategoryDataSource.
Рис. 6. Добавление нового объекта ObjectDataSource С именем ProductsInCategoryDataSource (щелкните, чтобы просмотреть изображение полного размера)
Настройте ObjectDataSource таким образом, чтобы он запускал метод класса GetProductsByCategoryID(categoryID)ProductsBLL.
Рис. 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>
На этом этапе у нас есть полностью функционирующий отчет с главной и детальной частью, который показывает название, цену за единицу, количество на складе и количество по заказу для продуктов, принадлежащих выбранной категории.
Рис. 9. Получение categoryID значения параметра из раскрывающегося списка выбранных категорий (щелкните, чтобы просмотреть изображение полного размера)
Шаг 2. Отображение нижнего колонтитула в GridView
Элемент управления GridView может отображать как строку заголовка, так и строку нижнего колонтитула. Эти строки отображаются в зависимости от значений свойств ShowHeader и ShowFooter соответственно, при этом ShowHeader по умолчанию равняется True, а ShowFooter - до False. Чтобы включить нижний колонтитул в GridView, просто установите значение свойства ShowFooter в True.
Рис. 10. Задайте для свойства ShowFooter GridView True значение (щелкните, чтобы просмотреть изображение полного размера)
Строка нижнего колонтитула содержит ячейку для каждого из полей, определенных в GridView; однако эти ячейки пусты по умолчанию. Ознакомьтесь с нашим прогрессом в браузере. Теперь для свойства ShowFooter задано значение True, и 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>
Как показано на снимке экрана ниже, это изменение делает нижний колонтитул более четким.
Рис. 12. Строка нижнего колонтитула GridView теперь имеет красный цвет фона (щелкните, чтобы просмотреть изображение полного размера)
Шаг 3. Вычисление сводных данных
При показе подвала GridView следующей задачей является подсчёт итоговых данных. Существует два способа вычисления этой статистической информации:
С помощью 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.Выполните вычисление этой информации по мере добавления в 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 записей, так как средняя цена является частным этих двух чисел.
Шаг 4. Отображение сводных данных в нижнем колонтитуле
Сводные данные подводятся последним шагом, чтобы отобразить их в строке нижнего колонтитула 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") сводная информация о средней цене будет отформатирована как валюта.
Рис. 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.