В предыдущей статье мы сделали обзор основных возможностей FastGrid — компонента сетки для Delphi из состава FastReport VCL. Теперь спустимся на уровень ниже и разберём внутреннее устройство компонента: изучим свойства сетки и визуальных элементов, из которых она состоит, рассмотрим объект View, колонки, их свойства и события, а в конце кратко коснёмся настройки работы с данными.
Материал будет полезен разработчикам на Delphi и C++ Builder, которые используют FastGrid в составе FastReport VCL или только планируют его освоить.
Сетка (TfrGrid) — основной контрол, на котором располагаются все остальные объекты, обеспечивающие её функционирование. Практически все свойства и события компонента стандартны и присутствуют у большинства элементов управления VCL. Исключение — два специфичных для сетки события:
Добавление и удаление различных View на сетку осуществляется с помощью меню компонента. При создании сетки в неё автоматически добавляется один объект View.
В дизайн-тайме на сетке также располагается легенда — небольшой список объектов, находящихся на сетке. В ней доступно меню не только для сетки, но и для расположенных на ней компонентов (колонок). Кроме того, легенда позволяет быстро активировать любой из этих компонентов. Если легенда не нужна, её можно убрать, установив у сетки свойство ShowLegend := False.
Объект View — основной элемент сетки, отвечающий за отображение её содержимого. Управлять объектами View можно с помощью легенды. В меню каждого View доступны следующие опции (в Unbound View некоторые из них отсутствуют):
При работе со сложными элементами управления вы постоянно сталкиваетесь с большим количеством свойств типа Color и Font, а также со свойствами вида ParentFont. В FastGrid все эти свойства спрятаны внутрь свойства Appearance. Оно состоит из вложенных свойств, каждое из которых отвечает за внешний вид той или иной части сетки.
Рассмотрим работу этих свойств на примере Appearance.Data — оно отвечает за внешний вид области данных сетки.
Как видно на скриншоте, это свойство состоит из вложенных свойств вида BackgroundColor, FontColor, FontName и набора флагов в подсвойстве AssignedValues с теми же именами. Принцип работы такой: с помощью AssignedValues мы указываем, что именно из набора простых свойств применяется непосредственно, а что наследуется от родительского объекта. Например, если установить AssignedValues.FontColor в True, то при изменении цвета шрифта у сетки цвет шрифта в области данных не изменится.
Свойства Appearance в основном применяются для настройки шрифта и цвета содержащих их объектов. Иными словами, они заменяют собой ParentColor, ParentFont и другие свойства со сходным поведением, но дают больше гибкости: часть параметров можно переопределить локально, а остальное наследовать от сетки.
Проверим, как это работает, на демо-проекте FastGrid. Откроем в Delphi проект GridDemo.dpr — он находится в меню «Пуск» в папке «FastReport VCL Products», в подпапке «2026.2.0-Sources-Demos» (номер версии в названии папки может отличаться; кроме того, в IDE должна быть установлена версия FastReport, в состав которой входит FastGrid). Откроем модуль DataAvareDemo.pas и перейдём к форме. Изменим некоторые вложенные свойства Appearance. Получилось так:
А теперь установим непосредственно у сетки свойство Font.Name := 'Courier New'. Такой шрифт выбран для наглядности. Внешний вид сетки станет таким:
Мы видим, что шрифт изменился у всех текстовых элементов сетки, однако цвет и атрибуты остались прежними. А у колонки City шрифт остался без изменений — мы установили его непосредственно у колонки. Такой подход позволяет более гибко управлять отображением содержимого сетки. Отметим: по умолчанию все AssignedValues установлены в False, то есть значения почти всех параметров берутся из сетки.
Все свойства объекта View сгруппированы в несколько групп.
Active — позволяет задать активность текущего View.
Appearance — определяет внешний вид объекта View. Если в AssignedValues соответствующий параметр установлен в False, значение берётся непосредственно из сетки:
DataController — свойство, задающее доступ к данным. Подробнее рассмотрим его в следующей статье.
OptionsBehavior — определяет поведение сетки. Вложенные свойства:
OptionsCustomization — разрешает пользователю те или иные операции: фильтрацию, группировку и сортировку данных; скрытие, перемещение и изменение размеров колонок и другие. Эти операции могут быть перекрыты аналогичным свойством для каждой колонки.
OptionsData — разрешает пользователю выполнять операции с данными сетки: вставку, добавление, удаление и редактирование.
OptionsDataNavigator — позволяет настроить навигатор данных: его позицию, прилегание к сторонам сетки, а также размер кнопок, их внешний вид и набор отображаемых кнопок.
OptionsView — позволяет настраивать внешний вид сетки. Рассмотрим некоторые подсвойства подробнее:
С объектами View можно работать и из кода. Создать новый объект можно следующей конструкцией: frGrid.Views.CreateView(TfrGridTableView).
Для удаления — удалить View из списка Views сетки (frGrid.Views.Remove(View)) или просто вызвать View.Free. Если требуется программно переключиться на другой View, достаточно установить у него View.Active := True.
Определить текущий активный столбец View можно с помощью свойства View.Controller.FocusedColumnIndex.
У объекта View предусмотрено множество событий, которыми программист может воспользоваться: как стандартные, например OnKeyDown, так и специфичные для сетки — их назначение в целом понятно из названий. Интересная особенность набора событий View (и не только его) — наличие у некоторых событий параметра var AAllow: Boolean. Установив этот параметр в False в обработчике события, программист легко запретит то или иное действие. Например, если установить его в обработчике OnEditing, мы запретим переход в режим редактирования для текущей ячейки.
Рассмотрим некоторые из событий View подробнее.
У этих событий есть общие элементы. Во всех обработчиках параметр AItem — это ссылка на колонку таблицы, а ARowIndex — номер строки данных в связанном с сеткой DataController.
View содержит в себе набор колонок. Колонки можно добавлять как в редакторе форм IDE, так и во время выполнения программы. Рассмотрим основные свойства колонки.
Appearance — определяет внешний вид колонки:
Caption — заголовок колонки.
DataBinding — свойство, определяющее привязку данных к колонке. Подробнее будет рассмотрено далее.
GroupIndex, MergedGroupIndex — индекс группы, в которой находится колонка, и индекс колонки в этой группе. По умолчанию равны -1 (колонка не входит в группу). Изменяя эти свойства, можно напрямую управлять группировкой в сетке — создавать и удалять группы. Если показ области группировки разрешён, пользователь в режиме выполнения может создавать и удалять группы самостоятельно: достаточно перетащить заголовок колонки в область группировки. Колонка при этом исчезнет из списка видимых, но данные в сетке будут сгруппированы по значению поля этой колонки. Отметим, что сетка всегда выполнит сортировку по этой колонке.
Группировка может быть многоуровневой — просто перетащите требуемые заголовки колонок. А если перетаскивать заголовок колонки с нажатой клавишей Ctrl, можно создать группу, основанную на нескольких колонках. Если группировка больше не нужна, перетащите заголовок колонки из области группировки обратно в сетку.
Index — видимый индекс колонки на экране. Изменяя это свойство, можно напрямую изменять положение колонки в сетке.
MinWidth — минимальная ширина колонки. Обратите внимание: по умолчанию это значение равно не 0, а 20.
Options — это свойство позволяет настроить, какие именно действия может производить пользователь с колонкой: переводить её в режим редактирования, фильтровать по данным колонки, группировать, скрывать колонку, изменять её размеры, перемещать её, изменять данные колонки, сортировать, а также показывать её в списке колонок. Как видно, этот список действий практически аналогичен тому, который находится в View.OptionsCustomization.
Properties — с помощью этого свойства можно задать редактор для использования в колонке. Если свойство не задавать, сетка попробует подобрать редактор на основании типа данных колонки. А если присвоить этому свойству значение из выпадающего списка, после этого его можно будет раскрыть и настроить свойства заданного редактора. Подробнее редакторы будут рассмотрены в отдельной статье. Пока отметим, что редактор отвечает не только за редактирование значения одной ячейки, но и за отображение значений всей колонки. Редакторы также доступны и как отдельные компоненты. Заметим, что доступ к свойствам редактора возможен только в том случае, если редактор задан явно: для редакторов по умолчанию возможность настройки свойств отсутствует.
SortOrderIndex, SortOrder — этими свойствами можно задать сортировку полей сетки. Поле SortOrderIndex отвечает за приоритет поля при сортировке: сначала производится сортировка по полю с SortOrderIndex = 0; если значения в этой колонке совпадут, то сортируем по колонке с SortOrderIndex = 1. Если задать SortOrderIndex = -1, сортировка по этой колонке не производится.
Свойство SortOrder определяет порядок сортировки: soNone — не сортируем, soAscending — сортировка по возрастанию, soDescending — по убыванию. Заметим, что задать сортировку колонок пользователь может и во время выполнения: достаточно щёлкнуть по заголовку колонки левой кнопкой мыши. При повторном щелчке порядок сортировки изменится на обратный. Сортировка будет выполняться по той колонке, на заголовок которой был выполнен щелчок. Для отмены сортировки достаточно щёлкнуть по заголовку колонки с нажатой клавишей Ctrl. А если при щелчке удерживать нажатой клавишу Shift, можно осуществить сортировку сразу по нескольким колонкам.
Создать колонку из кода можно с помощью метода View.Columns.CreateColumn. Задать ей редактор можно, присвоив свойству Column.PropertiesAlias строку с именем редактора или задав свойству Column.PropertiesClass тип класса редактора.
Очистить список колонок у View можно с помощью метода View.Columns.Clear. Также могут оказаться полезными свойства Columns.VisibleCount и Columns.VisibleItems — с их помощью можно получить доступ только к видимым колонкам, причём сами колонки в этом списке будут упорядочены по их положению на экране.
Рассмотрим события колонки данных. Как уже упоминалось, некоторые события колонки аналогичны событиям View.
В заключение статьи кратко рассмотрим настройку сетки на работу с данными на уровне задания свойств. Как мы уже знаем, сетка может работать с данными в двух режимах: DB и Unbound.
В режиме DB сетка связывается с данными, используя стандартный компонент TDataSource, аналогично тому, как это делает, например, стандартный компонент TDBGrid. После задания в инспекторе объектов View.DataController := 'DB' можно раскрыть это свойство и указать требуемый TDataSource. А после задания DataSource можно пройтись по колонкам и в свойстве DataBinding.FieldName каждой колонки указать имя требуемого поля данных. Свойство DataBinding.FieldType изменить нельзя — его значение берётся из связанного поля данных DataSource.
В режиме Unbound сетка работает немного иначе. После задания View.DataController := 'Unbound' сетка переходит в режим работы с данными, которые хранятся в самой сетке. Чтобы определить колонки набора данных, сначала нужно создать их — например, из всплывающего меню View в легенде, — затем перейти к объектам колонок и в поле DataBinding.FieldName каждой колонки задать имя поля данных, а в поле DataBinding.FieldType — тип поля данных. После этого во внутреннем хранилище сетки создаётся соответствующий набор полей, с которым можно работать.
Мы разобрали внутреннее устройство FastGrid: роль сетки как базового контрола, объект View и его свойства, механизм Appearance с подсвойством AssignedValues, колонки с их настройками и событиями, а также два режима работы с данными — DB и Unbound. Этого достаточно, чтобы настраивать внешний вид и поведение сетки как в дизайн-тайме, так и из кода.
Остался последний крупный вопрос — работа с данными: DataController, привязка DataSource, редактирование и навигация по записям. Именно его мы подробно рассмотрим в следующей статье цикла.