Розширення GridView

У наступних розділах розглядається кілька способів розширення GridView. Ви дізнаєтесь про те, як показати підсумкові значення, як створити повний звіт типу "головний-детальний" на одній сторінці та відобразити графічні дані, витягнуті з бази даних. Ви також побачите приклад, в якому використовується розширена обробка паралельного доступу для попередження користувача про потенційні конфлікти під час оновлення запису.

Підсумкові значення у GridView

Хоча основне призначення Gr >ShowFooter в true. Це призведе до відображення в нижній частині GridView затіненого рядка (який можна вільно налаштувати на свій смак), але жодні дані в ньому виводитися не будуть. Щоб вирішити це завдання, потрібно додати вміст у GridView.FooterRow.

Наприклад, припустимо, що йдеться про список товарів із тестової бази даних Northwind. Простий підсумковий рядок може відображати суму або середнє значення ціни товарів. У наступному прикладі підсумковий рядок відображатиме загальну кількість усіх товарів, що є на складі.

Перше, що потрібно зробити, вирішити, коли слід обчислювати цю інформацію. Якщо ви застосовуєте ручну прив'язку, можете витягти об'єкт даних і використовувати його для виконання обчислень до прив'язки до GridView. Однак, якщо ви застосовуєте декларативну прив'язку, необхідний інший підхід. На вибір доступні два варіанти - витягувати дані з об'єкта даних перед прив'язкою сітки або витягувати їх безпосередньо з самої сітки після того, як вона вже прив'язана.

У наступному прикладі використовується останній підхід, оскільки він надає свободу застосовувати той самий код обчислення підсумкових значень незалежно від того, яке джерело даних наповнює елемент управління. це такождає можливість підсумовувати лише рядки, що відображаються на поточній сторінці, якщо увімкнено розбиття на сторінки. Недолік рішення у цьому, що код був із GridView, т.к. необхідна інформація витягується за її позицією з використанням жорстко закодованих номерів стовпців.

У цьому прикладі таблиця товарів, що розділена на сторінки, надає підсумкову інформацію, що вказує загальну ціну всіх товарів, що відображаються в даний момент на сторінці:

розширення

Щоб заповнити нижній колонтитул, код у цьому прикладі реагує на подію GridView.DataBound. Воно відбувається негайно після того, як GridView наповнюється даними. У цій точці більше не можна звертатися до даних, але можна здійснювати навігацію GridView як по колекції рядка і осередків. Обчислене підсумкове значення вставляється у рядок нижнього колонтитула.

Нижче наведено повний код:

Підсумковий рядок має таку ж кількість стовпців, що й решта сітки. В результаті, якщо ви хочете, щоб текст поширювався на кілька осередків (як у даному прикладі), то маєте налаштувати це за допомогою властивості ColumnSpan відповідної комірки. У цьому прикладі перший осередок поширюється на три стовпці (власний стовпець і два сусідні справа).

Подання "батьківсько-дочірній" в одній таблиці

розширення

Базовий прийом передбачає створення GridView для батьківської таблиці, що містить вбудовані елементи GridView для кожного рядка. Ці дочірні елементи керування GridView розміщуються в батьківській GridView із застосуванням TemplateField. Єдина складність полягає в тому, що ви не можете прив'язати дочірні елементи керування GridView одночасно з прив'язкою батьківського елемента, оскільки батьківські рядки ще не створені. Натомість необхіднозачекати на виникнення події GridView.DataBound у батьківському елементі.

Отримання зображень із бази даних

У прикладах, розглянутих досі, витягувався текст, числа та дати. Однак, бази даних часто зберігають і двійкові дані, такі як графічні зображення. Наприклад, може існувати таблиця Products, яка містить зображення кожного елемента у двійковому полі. Витягти ці дані на сторінці ASP.NET досить просто, але не так просто їх відобразити.

Основна проблема полягає в тому, що для виведення зображення на HTML-сторінці необхідно додавати дескриптор графічного зображення, який посилається на окремий файл у своєму атрибуті src, як показано нижче:

На жаль, це не дуже допомагає, якщо потрібно динамічно відображати графічні дані. Хоча можна встановити атрибут src у коді, немає способу програмно встановити вміст зображення. Можна спочатку зберегти дані у графічному файлі на жорсткому диску веб-сервера, але такий підхід може виявитися надзвичайно повільним та марнотратним щодо дискового простору. Крім того, він також породжує помилки, пов'язані з паралельним доступом, коли одночасно обслуговується безліч запитів, і всі вони намагаються записати той самий файл.

У таких ситуаціях рішення полягає у застосуванні окремого ресурсу ASP.NET, який повертає двійкові дані безпосередньо. Ці двійкові дані можна використовувати в елементах керування на інших веб-сторінках. Щоб вирішити це завдання, також доведеться відмовитися від прив'язки даних і написати код користувача ASP.NET. Необхідне рішення крок за кроком розробляється в наступних розділах.

Як рекомендацію слід запам'ятати, що зберігання графічних зображень у базі даних добре працює тількитоді, коли вони не перевищують розумних розмірів (наприклад, 5 Мбайт) та не вимагають частого редагування у додатках.

Відображення двійкових даних

ASP.NET не обмежується поверненням HTML-вмісту. Насправді за допомогою методу Response. BinaryWrite() можна повертати неформатовані байти, повністю обминаючи модель веб-сторінок.

На наступній сторінці цей прийом використовується з таблицею pub_info в базі даних pubs (ще одна стандартна база даних, що постачається з SQL Server. Ви можете її встановити, використовуючи Northwind and pubs Sample Databases for SQL Server 2000). У цій сторінці виймається поле logo, що містить двійкові дані зображення. Потім ці дані безпосередньо виводяться на сторінку, як показано нижче:

Використовуючи BinaryWrite(), ви відступаєте від моделі веб-сторінки. Якщо ви додасте інші елементи керування на сторінку, вони не з'являться там. Аналогічно Response.Write() не дасть жодного ефекту, оскільки ви не конструюєте HTML-сторінку. Натомість ви повертаєте двійкові дані. У наступних розділах буде показано, як вирішити цю проблему та оптимізувати підхід.

Ефективне читання двійкових даних

Двійкові дані можуть легко зростати до великих розмірів. Однак якщо ви матимете справу з великим графічним файлом, то наведений вище приклад продемонструє низьку продуктивність. Проблема в тому, що використовується DataReader, який завантажує в пам'ять по одному запису за раз. Це краще, ніж DataSet (який завантажує відразу весь результуючий набір), але все ж таки не ідеально, якщо розмір поля досить великий.

Ось як переробити попередню сторінку для використання послідовного доступу:

Метод GetBytes() повертає значення, що вказуєкількість одержаних даних. Якщо потрібно визначити загальну кількість байт у полі, під час виклику методу GetBytes() просто передайте null-посилання замість буфера.

Інтеграція зображень з іншим вмістом

Метод Response.BinaryWrite() створює деяку проблему, якщо потрібно інтегрувати графічні дані з іншими елементами керування та HTML-розміткою. Це пояснюється тим, що у разі використання BinaryWrite() для повернення низькорівневих даних зображення втрачається можливість додавати будь-який додатковий HTML-вміст.

Щоб вирішити цю проблему, потрібно створити іншу сторінку, яка викличе код, що генерує зображення. Найкращий спосіб зробити це – замінити сторінку, що генерує зображення, виділеним обробником HTTP, який згенерує графічний висновок. В результаті вдасться заощадити на витратах повної моделі веб-форм ASP.NET. яку все одно використовувати не можна.

Створити потрібний обробник HTTP досить легко. Ви повинні реалізувати інтерфейс IHttpHandler та метод ProcessRequest(). Обробник HTTP витягне ідентифікатор запису, який потрібно відобразити з рядка запиту.

Нижче наведено повний код обробника HTTP:

Створений обробник HTTP необхідно додати у файл типу Generic Handler:

GridView

Тепер можна отримувати графічні дані, опитуючи URL обробника HTTP, вказуючи ідентифікатор (ID) рядка, який потрібно вийняти. Ось приклад:

Нижче наведено приклад реалізації сторінки з безліччю елементів керування та зображеннями логотипів. Вона використовує в GridView наступний шаблон ItemTemplate:

даних

Цей підхід з обробником HTTP добре працює, коли потрібно створити детальну сторінку з інформацією про окремий запис. Наприклад, ви можете виводитисписок видавців, а потім показувати графічне зображення, що символізує видавця, коли користувач робить вибір. Однак це рішення не таке ефективне, якщо потрібно відобразити відразу всі графічні зображення для всіх видавців, наприклад, у списковому елементі управління. Підхід працює, але досить ефективно, т.к. для вилучення кожного зображення використовується окремий запит до обробника HTTP (а тому і додаткове з'єднання з базою даних).

Вирішити цю проблему можна за рахунок створення обробника HTTP, який спочатку перевіряє наявність зображення в кеші, перш ніж виймати його з бази даних. Тоді перед прив'язкою GridView потрібно буде виконати запит, який поверне всі записи зі своїми графічними даними та завантажить їх у кеш.