Сортування колонок в dbgrid - delphi sources faq

Дзвінок Користувача в службу підтримки.
- Алло, це служба підтримки.
- Так.
- У мене проблема, мій модем не хоче працювати.
- Давайте пропишемо Вам рядок ініціалізації.
- Давайте.
- ATF1M5
- Дякуємо. Через 5 хвилин.
- У мене все ще не працює.
- Так. Ну давайте запишіть іншу
- Я слухаю
- ATS10 = 100
- Дякуємо!
Проходить ще 5 хвилин.
- У мене Модем все ще погано працює.
- Ну що, пишіть ще одну сходинку.
- Слухаю.
- ATFB1A0S0 = 90
- Дякуємо. Минуло ще 5 хвилин.
- Алло. У мене згорів модем.
- Шкода, а то у мене ще стільки в запасі рядків ініціалізацій залишилося.

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

Головна перешкода в рішенні завдання - сам DBGrid. Проблема у відсутності подій OnClick або OnMouseDown, що дозволяють реагувати на елементарні маніпуляції із заголовком. Правда, існує подія OnDoubleClick, але для даної мети воно не дуже витончено. Все що нам потрібно - зробити заголовок, що реагує на одноразовий клацання мишею. Звернемося до компоненту THeaderControl.

THeaderControl - компонент, введений в палітру ще в Delphi 2.0 і забезпечує необхідні нам функції. Головне достоїнство - реакція компоненту при натисканні на окремих панелях, панелі також забезпечують візульних відображення подібно кнопці (можуть вдавлюватися і віджиматися). Нам необхідно "прикрутити" THeaderControl до DBGrid. Ось як це зробити:

По-перше, створіть новий додаток. Покладіть THeaderControl на форму. Він автоматично вирівняється по верхньому краю форми. Потім помістіть на форму DBGrid і надайте властивості Align значення alClient. Потім додайте компоненти TTable і TDataSource. У компоненті TTable надайте властивості DatabaseName значення DBDEMOS, а властивості TableName значення EVENTS.DB. У TDataSource вкажіть у властивості DataSet на компонент Table1, а в TDBGrid у властивості DataSource на DataSource1. Якщо властивість Active компонента TTable було неактивно, включите його (значення True). Тепер трохи поколдуем!

Зробимо так, щоб компонент THeaderControl виглядав схожим на заголовок компонента DBGrid. Зробимо необхідні маніпуліціі в момент створення форми. Двічі клацніть на подію OnCreate форми і введіть наступний код:

Після того як THeaderControl замінив стандартний заголовок DBGrid, в першу чергу ми скидаємо (встановлюємо в False) прапор dgTitles у властивості Options компонента DBGrid. Потім ми додаємо колонку в HeaderControl і встановлюємо її ширину, рівну 12. Це буде порожньою колонкою, яка має ту ж ширину, що і ліва колонка статусу в DBGrid.

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

Тепер додаємо секції в HeaderControl. Для кожної доданої колонки ми створюємо в заголовку той же текст, що і у відповідній колонці DBGrid. У циклі ми проходимо по всіх колонках DBGrid і повторюємо текст заголовка колонки і його висоту. Ми також встановлюємо для HeaderControl значення властивостей MinWidth і MaxWidth, рівними ширині відповідної колонки в DBGrid. Це охоронить колонки від зміни їх ширини. Для змінюють розмір колонок потрібно додаткове кодування, і я вирішив не позбавляти Вас цього задоволення.

Тепер найцікавіше. Ми збираємося створити індекс для кожної колонки в DBGrid. Ім'я індексу буде таким же, як і назва колонки. Даний код ми повинні укласти в конструкцію try..finally, оскільки існують деякі поля, які не можуть бути проіндексовані (наприклад, Blob- і Memo-поля). При спробі індексації цих полів генерується виняткова ситуація. Ми перехоплюємо це виняток і недопускати можливості клацання на цій колонці. Це означає, що колонки, що містять неіндексовані поля, не реагуватимуть на клацання мишею. Створення цих індексів є поясненням того, чому таблиця повинна бути відкрита в режимі ексклюзивного доступу. І на закінчення ми закриваємо таблицю, скидаємо прапор ексклюзивності і знову робимо таблицю активною.

Останній крок. При натисканні на HeaderControl нам необхідно включити правильний індекс таблиці. Створимо оброблювач події OnSectionClick компонента HeaderControl як показано нижче:

Це все! Після клацання на заголовку колонки значення властивості таблиці IndexName стає рівним заголовку компоненту HeaderControl.

Просто і красиво, да? Проте є маса місць, які потребують поліпшення. Наприклад, вторинний клацання повинне відновлювати порядок сортування. Або можливість зміни розміру самих колонок. Спробуйте самі, це не складно!

Тут наведено покращений код в порівнянні з попередньою версією "Ради", він полягає в використанні в якості імені індексу ім'я поля замість заголовка.

Це покращує гнучкість. Зміни вказані похилим курсивом.

Використовуйте властивість FieldName компонента DBGrid для завдання індексу з тим же ім'ям, що і ім'я поля.

Схожі статті