Страница 24 из 59 Компонент TDrawGrid TObject-”TPersistent->TComponent-”TControl—>TWinControl-> —”TCusto:mControl—>TCustomGrid—>TDrawGrid Модуль GRIDS Страница Палитры компонентов Additional Использование этого компонента дает универсальный способ организовать представление информации в виде таблицы. TDrawGrid берет на себя разбивку области на прямоугольные ячейки, добавление и удаление строк и столбцов, прокрутку, управление вводом данных и обработку всех поступающих сообщений. Единственное, что должен сделать программист — это нарисовать или написать то, что ему нужно, в каждой ячейке. Таблица делится на две области — фиксированную и подвижную. Фиксированную область обычно составляют часть строк и столбцов в верхней части таблицы. Такие ячейки необходимы, например, для вертикальных и горизонтальных заголовков. Они выделяются другим цветом, всегда видимы и в прок-. рутке не участвуют, оставаясь на своих местах. Их нельзя сфокусировать и выделить. Кроме того, изменять ширину и высоту ячеек таблицы мышью во время исполнения можно только передвигая границы ячеек в фиксированной области. По умолчанию для этой области отведены один столбец и одна строка, но эти числа могут быть изменены. Все остальные ячейки перемещаются при прокрутке таблицы и составляют подвижную область. Значение текста ячейки может редактироваться — для этого есть собственный встроенный редактор, являющийся потомком TMaskEdit. Свойства TDrawGrid, определяющие его внешний вид, приведены в таблице: (pb) property ColCount: Longint; (Pb) property RowCount: Longint; | Содержат количество строк и столбцов в таблице. Обратите внимание, что координаты ячеек в таблице имеют тип Longint, т. е. в принципе число строк и(или) столбцов может превышать 65535. | property Col:Longint; property Row •.Longint; | Содержат номера столбца и строки, содержащих сфокусированную ячейку. | property ColWidths[Index: Longint]: Integer; property RowHeights[Index: Longint]: Integer; | Свойства-массивы, содержащие ширину каждого столбца и высоту каждой строки. (Ширина и высота ячеек могут быть индивидуальными, см. свойство Options.) | § property DefaultColWidth: Integer; property DefaultRowHeight: Integer; | Содержат ширину столбца и высоту строки, принимаемые по умолчанию. Они применяются при начальной инициализации таблицы и при добавлении в нее ячеек. | (Ro) property GridHeight: Integer; (Ro) property GridWidth: Integer; | Содержат высоту и ширину всей таблицы. Эти свойства доступны только для чтения, так как являются производными от числа ячеек и их размеров. | (Pb) property ScrollBars: TScrollStyle; TScrollStyle = (ssNone, ssHorizontal, ssVerticai, ssBoth) ; | Задает полосу прокрутки. Если все ячейки не помещаются в область, отведенную компоненту, появляются полосы прокрутки в нужном направлении. По умолчанию предусмотрены обе полосы прокрутки. | J property FixedCols: Integer; property FixedRows: Integer; | Содержат соответственно число строк и столбцов в фиксированной области. | (Pb) property FixedColor: TColor; | Содержит цвет, которым происходит закрашивание ячеек фиксированной области. | property TopRow: Longint; property LeftCol: Longint; | Содержат номера верхней строки и левого столбца, видимых в подвижной области. Первоначально это первая ячейка за фиксированной областью (TopRow = FixedRows, LeftCol = FixedCols), однако при прокрутке и других перемещениях сфокусированной ячейки эти значения могут изменяться. Свойства доступны только во время исполнения. | (Pb) property OnTopLeftChanged: TNotifyEvent; | Событие вызывается, когда изменяются TopRow или LeftCol. | property VisibleColCount: Integer; property VisibleRowCount: Integer; | Содержат соответственно число полностью видимых столбцов и строк в подвижной области. Могут быть не полностью видны еще один столбец и одна строка. | Рассматриваемый компонент имеет множество вариантов настройки под конкретное применение. Изменить его функционирование вы можете, настроив соответствующим образом опции: (Pb) property Options: TGridOptions; TGridOption = (goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goDrawFocusSelected, goRowSizing, goColSizing, goRowMoving, goColMoving, goEditing, goTabs, goRowSelect, goAlwaysShowEditor, goThumbTracking) ; TGridOptions = set of TGridOption; В множестве допускаются сочетания следующих опций: goFixedVertLine — ячейки в фиксированной области разделяются вертикальными линиями; goFixedHorzLine — ячейки в фиксированной области разделяются горизонтальными линиями; goVertLine — ячейки разделяются вертикальными линиями; goHorzLine — ячейки разделяются горизонтальными линиями; goRangeSelect — может быть выделено множество ячеек; goDrawFocusSelected — при наличии опции ячейка, имеющая фокус, рисуется тем же цветом, что и выделенная. В противном случае — имеет цвет обычных ячеек (но выделяется, как всегда, рамкой из отдельных точек); goRowSizing — высота строк может изменяться индивидуально; goColSizing — ширина столбцов может изменяться индивидуально; goRowMoving — строки могут быть перемещены мышью; goColMoving — столбцы могут быть перемещены мышью; goEditing — ячейки таблицы могут редактироваться; goAlwaysShowEditor — содержимое активной (сфокусированной) ячейки всегда загружается в редактор (в противном случае требуется нажатие <F2> или щелчок мышью); goTabs — переход между столбцами возможен при помощи табуляции (<ТаЬ> или <Shift>+<Tab); goRowSelect — если эта опция присутствует, в таблице нельзя выделить единственную ячейку (кроме левой нижней из видимых). Выделяется всегда текущий столбец или область ячеек от левой нижней до текущей; goThumbTracking — задает поведение ячейки при передвижении мышью бегунка полосы прокрутки. Если эта опция отсутствует, содержимое ячеек не обновляется, пока пользователь не отпустит кнопку мыши; иначе — перерисовка происходит при каждом изменении. Толщина линий, разделяющих ячейки таблицы, задается свойством: (Pb) property GridLineWidth: Integer; Линии в вертикальном и горизонтальном направлениях рисуются в случае наличия опций [goFixedVertLine, goVertLine] и [goFixedHorzLine, goHorzLine] соответственно. Метод function CellRect(ACol, ARow: Longint): TRect; возвращает прямоугольник, соответствующий ячейке с индексами ACol, ARow в системе координат клиентской области таблицы. Метод MouseToCell превращает координаты точки нажатия кнопки мыши в индексы строки и столбца, где оно произошло: procedure MouseToCell (X, Y: Integer; var ACol, ARow: Longint); Вообще говоря, мышь ни при чем и преобразуются любые координаты, заданные относительно начала клиентской области. В сфокусированной ячейке редактор ячеек таблицы можно вызвать вводом любого символа ASCII или <F2>. Указывает, активен ли редактор, свойство: property EditorMode: boolean; Оно не имеет смысла, если редактор активен постоянно (установлена опция goAlwaysShowEditor). Если установлен режим goTabs, то между столбцами таблицы можно передвигаться, нажимая <ТаЬ> или <Shift>+<Tab>. По умолчанию фокус будет останавливаться на всех столбцах. Чтобы исключить остановку на некоторых столбцах, нужно присвоить значение False элементу массива TabStops с нужным индексом: (Pb) property TabStops[Index: Longint]: Boolean; He путайте это свойство с TabStop, которое касается всего компонента. Событие, возникающее при смене сфокусированной ячейки: (Pb) property OnSelectCell: TSelectCellEvent; TSelectCellEvent = procedure (Sender: TObject; Col, Row: Longint; var CanSelect: Boolean) of object; Фокус должен переместиться в ячейку (Col, Row). Изменяя значение параметра CanSelect, можно запретить перемещение фокуса в некоторые ячейки. Прямоугольник, соответствующий диапазону выделенных ячеек, содержится в свойстве: property Selection: TGridRect; TGridRect = record case Integer of 0: (Left, 'I'op, Right, Bottom: Longint); 1: (TopLeft, BottomRight: TGridCoord); end; TGridCoord = record X: Longint; Y: Longint; end; Стиль обрамления всей таблицы задается: (Pb) property BorderStyle: TBorderStyle; При bsSingle компонент окаймляется черной линией. Перейдем к тому, как помещать и отображать информацию в ячейки TDrawGrid. Если вы вводите текст, то он виден в редакторе, возникшем в текущей ячейке. Но как только ввод завершен, текст исчезает. Почему? TDrawGrid возлагает на программиста обязанность нарисовать содержимое каждой ячейки. Если свойство (Pb) property DefaultDrawing: Boolean; установлено 6 True, для всех состояний ячеек предусматривается отрисовка по умолчанию, а именно заливка ячейки определенным для данного состояния цветом. Только установив его в False, программист получает доступ к обработке событий OnDrawCell и может изобразить каждую ячейку таблицы так, как ему требуется. Для этого таблица имеет свою канву: property Canvas: TCanvas ; Обработчик события OnDrawCell должен иметь тип: (Pb) property OnDrawCell: TDrawCellEvent; TDrawCellEvent = procedure (Sender: TObject; Col, Row: Longint; Rect: TRect; State: TGridDrawState) of object; Параметры: Col, Row — координаты (номера столбца и строки) ячейки; Rect — отведенный ей прямоугольник; State — состояние ячейки. Описывается флагами из множества: TGridDrawState = set of (gdSelected, gdFocused, gdFixed) ; Флаги соответствуют выбранной, сфокусированной ячейкам и ячейке из фиксированной области. Приведенный ниже фрагмент кода закрашивает ячейки таблицы разным цветом в зависимости от значений во внешнем массиве Field: procedure TFormI-DrawGridlDrawCell(Sender: TObject; Col, Row: Longint; Rect: TRect; State: TGridDrawState); begin with DrawGridI.Canvas do begin if Field[Col,Row] then Brush.Color := clAqua else Brush.Color := clBackground; FillRect(Rect) ,-end; end ; При установленных опциях goColMoving/goRowMoving можно захватить мьппью ячейку заголовка (в фиксированной области) и перенести всю строку или столбец на другое место. В этом случае после нажатия левой кнопки мыши появляется вертикальная или горизонтальная линия, показывающая, куда будет вставлена перемещаемая информация: при движении к началу таблицы — за линией, к концу — перед ней. При этом корректируются размеры выделенной области. Строки и столбцы заголовков, полностью лежащие в фиксированной области, переносить нельзя. По окончании переноса происходят события, которые информируют о перемещении столбца или строки из положения Fromlndex в положение Tolndex: (pb) property OnColumnMoved: TMovedEvent ; (Pb) property OnRowMoved: TMovedEvent; TMovedEvent = procedure (Sender: TObject; Fromlndex, Tolndex: Longint) of object; В редактируемой таблице (при установленном goEditing) есть возможность реагировать на связанные с изменением текста события. В начале (при вызове редактора) можно задать маску для редактирования ячейки, вернув ее в параметре Value обработчика события OnGetEditMask. Напомним, что редактор ячейки таблицы является потомком TMaskEdit: (Pb) property OnGetEditMask: TGetEdiCEvent; TGetEditEvent = procedure (Sender: TObject; ACol, ARow: Longint; var Value: string) of object; Далее редактор извлекает текст, связанный с ячейкой. При этом вызывается событие: (Pb) property OnGetEditText: TGetEditEvent; Загружаемый текст доступен в параметре Value, и его можно изменить до появления в редакторе. При каждом изменении текста в редакторе инициируется событие: (Pb) property OnSetEditText: TSetEditEvent; TSetEditEvent = procedure (Sender: TObject'; ACol, ARow: Longint; const Value: string) of object; Иллюстрирует применение TDrawGrid пример LIFE. Это классическая игра "жизнь" (автор — X. Конвей), имитирующая законы выживания. Каждая ячейка таблицы здесь соответствует одному "существу". Его состояние изменяется через некоторые интервалы времени (для этого используется компонент TTimer). Существо "живет" нормально, если у него двое или трое соседей. Если их меньше, оно умирает от одиночества, если больше — от перенаселения. Новая жизнь появляется в пустой ячейке, если у нее ровно трое соседей. Начальное состояние ячеек может быть случайным, а может быть задано вами: щелчок по ячейке означает изменение ее состояния. Запустив игру, вы увидите, как постепенно положение на игровом поле стабилизируется, и на нем образуется несколько разновидностей устойчивых конфигураций групп ячеек. |