Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на Pascal / Delphi / Справочник по компонентам Delphi.doc
Скачиваний:
148
Добавлен:
02.05.2014
Размер:
1 Mб
Скачать

Компонент tSpinEdit

TObject-”TPersistent—>TComponent-”TControl->TWinControl—>TCustomEdit-”

->TSpinEdit

Модуль SPIN

Страница Палитры компонентов Samples

Этот компонент представляет собой комбинацию обычного редактирующего элемента и кнопки со стрелками вверх и вниз (TSpinButton). Такие элементы управления стали практически повсеместными для редактирования числовых величин. При большом изменении величины удобней набрать ее в редакторе заново, а в случае небольшого — скорректировать несколькими нажатиями стрелок. Свойства компонента приведены в таблице:

-1

(Ro) property Button: TSpinButton;

Содержит указатель на кнопку, через который можно обратиться к ее свойствам и методам.

(Pb) property EditorEnabled: Boolean;

В состоянии False запрещает изменение значений в редакторе.

(Pb) property Readonly: Boolean;

В состоянии False полностью запрещает изменение значений (при помощи кнопок и редактора).

(Pb) property MinValue: Longint;

Содержит минимальное допустимое значение.

(pb) property MaxValue: Longint;

Содержит максимальное допустимое значение.

(Pb) property MaxLength: Integer;

Содержит значение максимального количества символов (цифр, знаков '-' и '+')в редакторе.

(fb) property Increment: Longint;

Содержит величину, на которую изменяется значение в редакторе при каждом нажатии кнопки.

(Pb) property Value: Longint;

Содержит текущее значение.

Щелчки мышью на компоненте интерпретируются следующим образом. Если щелчок или двойной щелчок произошли над областью редактора, то возникают соответственно события:

(Pb) property OnClick: TNotifyEvent;

(РЕ) property OnDblClick: TNotifyEvent;

Если щелчок произошел над областью кнопки, то возникают специфические для нее события OnUpClick или OnDownClick, а в самом компоненте только отражается произошедшее изменение:

(Pb) property OnChange: TNotifyEvent;

Событие OnChange возникает также при редактировании текста (если оно не запрещено). Если нажать и не отпускать одну из кнопок, то в это время соответствующие события происходят периодически (период 400 мс).

3.2.6. Создание таблиц и иерархических структур

В эту группу входят только три компонента — TDrawGrid, TStringGrid и TOutline. Это, если можно так выразиться, элементы управления "второго поколения" — они решают гораздо более сложные задачи, чем традиционный набор средств Windows, но при этом и устроены намного сложнее.

Компонент 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). Существо "живет" нормально, если у него двое или трое соседей. Если их меньше, оно умирает от одиночества, если больше — от перенаселения. Новая жизнь появляется в пустой ячейке, если у нее ровно трое соседей. Начальное состояние ячеек может быть случайным, а может быть задано вами:

щелчок по ячейке означает изменение ее состояния. Запустив игру, вы увидите, как постепенно положение на игровом поле стабилизируется, и на нем обра­зуется несколько разновидностей устойчивых конфигураций групп ячеек.

Компонент TStringGrid

TObject-”TPersistent—>TComponent-*TControl-”TWinControl-> —”TCustomControl-”TCustomGrid-”TDrawGrid->TStringGrid Модуль GRIDS Страница Палитры компонентов Additional

Этот компонент реализует возможности своего предка TDrawGrid применитель­но к таблице строк.

В состав компонента добавлен объект класса TStrings, в котором хранится содержимое ячеек. Он доступен как векторное свойство — двумерный массив текстовых строк (размерностью ColCount x RowCount), соответствующих ячей­кам таблицы:

property Cells[ACol, ARow: Integer]: string;

Доступен и двумерньш массив объектов, соответствующих ячейкам:

property Objects[ACol, ARow: Integer]: TObject;

Необходимо помнить, что самих объектов в таблице нет, и программист должен создавать, а по окончании использования таблицы удалять объекты самостоятельно.

Можно работать отдельно как со строками, так и со столбцами таблицы. Свойства

property Cols[Index: Integer]: TStrings;

property Rows[Index: Integer]: TStrings;

описывают наборы строк (также в виде TStrings), содержащие текст и объекты столбцов и строк таблицы.

При значении True свойства DefaultDrawing для этого компонента происходит вывод строки в соответствующей ячейке. Так что если кроме текста ничего отображать не требуется, то менять значение DefaultDrawing и определять обработчик события OnDrawCell не нужно.

Отметим, что перенос строк и столбцов таблицы (при установленных опциях goColMoving или goRowMoving) осуществляется вместе с их текстовыми стро­ками.

Компонент TOutline

TObject->TPersistent—>TCoinponent—”TControl—”TWinControl-> —>TCustomControl->TCustomGrid->TCustomOutline-”TOutline Модуль OUTLINE Страница Палитры компонентов Additional

TOutline создан для ведения и отображения иерархических структур данных — деревьев. Это один из наиболее сложных и интересных компонентов. В этот раздел он попал потому, что является потомком таблицы (TCustomGrid), хотя и мало чем ее напоминает.

Типичным примером применения TOutline можно назвать отображение структуры файловой системы (для этого даже есть отдельный компонент TDirectory Outline). В описанном ниже примере OBJTREE этот компонент используется для отображения дерева классов библиотеки VCL.

Дерево состоит из элементов (будем называть их узлами), упорядоченных по уровням. Каждый из них имеет родительский узел (на более высоком уровне) и список дочерних узлов-потомков. Исключением являются корневой узел (ну­левого уровня) — он не имеет предка, и узлы последнего уровня, не имеющие потомков.

Каждый узел является объектом класса TOutlineNode:

TOutlineNode = class(TPersistent) Рассмотрим сначала методы и свойства этого объекта. С каждым узлом можно связать информацию — имя и произвольные данные:

property Text: string;

property Data: Pointer;

Указатель на родительский узел определяется свойством:

(Ro) property Parent: TOutlineNode;

Если список дочерних узлов не пуст, что можно проверить при помощи свой­ства

(Ro) property Hasltems: Boolean;

то для получения информации о них есть метода,!:

function GetFirstChild: Longint;

function GetLastChild: Longint;

function GetNextChild(Value: Longint): Longing-function GetPrevChiId(Value: Longint): Longint;

В последних двух методах параметр Value содержит индекс предыдущего най­денного потомка. Индекс — это уникальный идентификатор узла в дереве, определенный свойством:

(Ro) property Index: Longint;

Используя его, можно получить указатель на узел (см. ниже сам компонент TOutline). Узлы пронумерованы таким образом, что если родитель имеет номер N, то первый из его потомков — номер (N+1).

Можно узнать и полное имя (путь) узла, представляющее собой конкатенацию всех родительских имен и имени узла, разделенных специальным символом. Этот символ определен в свойстве ItemSeparator объекта TCustomOutline, ко­торому принадлежат узлы. Полный путь определяется свойством:

(Ro) property FullPath: string;

Каждый узел расположен на своем иерархическом уровне. На самом верху находится узел уровня 0. Все другие являются для пего дочерними; он не виден и не доступен пользователю. Поэтому на первом доступном уровне — с номером 1 — могут находиться по вашему желанию один или несколько узлов. Уровень иерархии узла можно узнать в его свойстве:

(ro) property Level: Cardinal;

Чтобы изменить уровень, надо вызвать метод:

procedure ChangeLevelBy(Value: TChangeRange);

которьш перемещает узел в список другого уровня. Диапазон перемещения TChangeRange ограничен:

TChangeRange = -1..1;

Чтобы переместить узел в дереве, нужно вызвать следующий метод

procedure MoveTo(Destination: Longint; AttachMode: TAttachMode);

TAttachMode = (oaAdd, oaAddChild, oalnsert) ;

Он перемещает узел (вместе со всеми потомками) в положение с индексом Destination. Родительский узел не может переместиться на место любого из своих потомков. Режим перемещения AttachMode означает:

oaAdd — добавить последним на том же уровне, что и Destination;

oaAddChild — добавить последним к потомкам узла Destination;

oalnsert — заменить в положении Destination прежний узел, которьш сме­щается дальше по списку на том же уровне.

Индекс того из предков узла, которьш находится в списке самого высокого уровня, известен из свойства:

(Ro) property Topltem: Longint;

Для корневого узла это свойство равно 0.

Компонент TOutline не только хранит древовидную структуру, он еще и отоб­ражает ее. На экране каждый узел может находиться в двух состояниях, свер­

нутом и развернутом. В свернутом состоянии потомки узла не видны, в раз­вернутом они изображаются чуть ниже и правее друг под другом. Состояние узла может иллюстрироваться значком (плюс/минус, открытая/закрытая папка — см. описание свойства OutlineStyle компонента TOutline). В таблице приведены методы и свойства, управляющие состоянием узла на экране:

property Expanded: Boolean;

Указывает, в каком состоянии находится узел; True — развернутое состояние.

procedure Collapse;

Сворачивает узел, пряча все дочерние узлы.

procedure Expand;

Разворачивает узел списка, показывая дочерние узлы.

procedure FullExpand;

Полностью разворачивает узел, показывая все дочерние узлы всех подуровней.

Сворачивать/разворачивать узлы дерева, помимо щелчков мышью, можно нажатием клавиш:

<+> — соответствует Expand;

<-> — соответствует Collapse;

<*> — соответствует FullExpand. Свойство

(Ro) property IsVisible: Boolean;

означает, может ли быть виден узел. Это возможно только в том случае, если виднь! все его родители. При отрисовке ширина узла сообщается методом:

function GetDisplayWidth: Integer;

Теперь перейдем от описания узла к описанию самого дерева — компонента TOutline. Он представляет собой совокупность узлов типа TOutlineNode. Всего в дереве содержится число узлов, равное значению свойства:

(Ro) property ItemCount: Longint;

К каждому из них можно обратиться, используя свойство:

(Ro) property Items[Index: Longint]: TOutlineNode;

На текущий (выделенный) узел можно сослаться через свойство:

property Selectedltem: Longint;

Например, выполнение оператора

Items[Items[Selectedltem].Topltem].FullExpand;

приведет в развернутое состояние ту часть дерева, в которой находится вы­деленный узел (начиная от его самого далекого предка Topltem). Свойство

property Row: Longint;

показывает, какая строка дерева в данный момент имеет фокус. Зная "содержимое" узла, то есть его имя или данные, можно найти его в дереве и узнать индекс. Для этого нужно вызвать один из методов, возвра­щающих его:

function GetDataItem(Value: Pointer): Longint;

function GetTextItem(const Value: string): Longint;

Можно найти узел и по координатам точки в клиентской области компонента (на самом деле играет роль только координата Y) с помощью следующего метода:

function GetItemfX, Y: Integer): LongInC;

Целых три пары методов добавляют новый узел в дерево. Его имя инициализируется параметром Text. Различие между первым и вторым мето­дами в парах в том, что второй позволяет связать с узлом данные (параметр Data), а в первом вместо них записывается nil.

function Add(Index: Longint; const Text: string): Longint;

function AddObject(Index: Longint; const Text: string;

const Data: Pointer): Longint;

— добавляют новый узел в качестве последнего в тот же список, где находится узел Index. Поскольку на самом верху иерархии может быть только один узел, то в случае задания Index = 0 он добавляется в список верхнего уровня. Соответствуют режиму oaAdd;

function AddChild(Index: Longint; const Text: string): Longint;

function AddChildObject(Index: Longint; const To" : string;

const Data: Pointer): Longint;

— добавляют новый узел в качестве последнего потомка узла Index. Соответ­ствуют режиму oaAddChild;

function Insert(Index: Longint; const Text: string): Longint;

function InsertObject(Index: Longint; const Text: string;

const Data: Pointer): Longint;

— вставляют узел в положение Index. При этом прежний узел с таким индексом и все другие на этом уровне сдвигаются вниз. Единственное исключение — задание в качестве параметра нулевого индекса. В этом случае узел добавляется последним в список самого верхнего уровня. Соответствуют режиму oalnsert. Все методы вызывают переиндексирование дерева и возвращают уже новый индекс для вставленного узла. Если нужно удалить узел, то метод procedure Delete(Index: Longint);

удаляет узел с индексом Index, а метод

procedure Clear;

очищает все дерево.

Если нужно вставить или удалить сразу много узлов и при этом избежать трудоемких операций переиндексации и перерисовки дерева, то соответству­ющий код надо заключить между вызовами методов:

procedure BeginUpdate;

procedure EndUpdate;

Первый устанавливает специальное состояние обновления и на время запрещает все пересчеты и перерисовки, а второй сбрасывает его и обновляет дерево. Это состояние можно изменить и при помощи метода:

procedure SetUpdateSCate(Value: Boolean);

Дерево можно полностью свернуть или полностью развернуть вызовом мето­дов:

procedure FullExpand;

procedure FullCollapse;

Каждый узел, изменяя свое состояние, предупреждает об этом родительское дерево. В зависимости от того, свернулся он или развернулся, вызываются обработчики событий

(pb) property OnExpand: EOutlineChange;

(РЬ) property OnCollapse: EOutlineChange;

EOutlineChange = procedure (Sender: TObject; Index: Longint) of object;

где параметр Index означает индекс узла, измешшшего состояние. Метод

function GetNodeDisplayWidth(Node: TOutlineNode): Integer;

возвращает ширину, занимаемую изображением узла (если установленньш стиль не osOwnerDraw, см. ниже).

Дерево может быть загружено и выгружено в поток и файл при помощи методов:

procedure LoadFromFile(const FileName: strings-procedure LoadFromStream(Stream: TStream);

procedure SaveToFile(const FileName: strings-procedure SaveToStream(Stream: TStream) ;

Для прокрутки информации TOutline по умолчанию имеет обе полосы, опре­деляемые свойством:

(Pb) property ScrollBars: TScrollStyle;

TScrollStyle = (ssNone, ssHorizontal, ssVertical, ssBoth);

Строка (символ), разделяющий имена узлов при составлении полного имени узла, содержится в свойстве:

(Pb) property ItemSeparator: string;

На стадии разработки можно набрать строки, соответствующие будущим узлам дерева, в специальном редакторе. При этом узел попадет на уровень, соответ­ствующий количеству пробелов или знаков табуляции перед его названием. Набранные строки текста содержит свойство:

(Pb) property Lines: TStrings;

Это свойство предназначено для использования именно на этапе разработки, так как свойство Items в это время недоступно. Во время исполнения с инфор­мацией об узлах нужно работать, используя свойство Items. При рисовании дерева, помимо собственно текста, вместе с ним может изоб­ражаться одна из пиктограмм:

Из) property PicturePlus: TBitmap;

Соответствует свернутому узлу. По умолчанию — "плюс".

(Pb) property PictureMinus: TBitmap;

Соответствует развернутому узлу. По умолчанию — "минус".

(Pb) property PictureOpen: TBitmap;

Соответствует развернутому узлу. По умолчанию — "открытая папка".

(Pb) property PictureClosed: TBitmap;

Соответствует свернутому узлу. По умолчанию — "закрытая папка".

(Pb) property PictureLeaf: TBitmap;

Соответствует "листу" — узлу без потомков. По умолчанию — "документ".

Желательно, чтобы картинки имели "прозрачный" фон, то есть чтобы их свойство TransparentColor соответствовало цвету рабочей области компонента. Эти пиктограммы можно переопределить в случае необходимости.

Свойство OutlineStyle определяет, в частности, когда и какие пиктограммы будут показаны:

(Pb) property OutlineStyle: TOutlineStyle;

TOutlineStyle = (osText, osPlusMinusText, osPictureText, osPlusMinusPictureText, osTreeText, osTreePictureText);

В зависимости от значения этого свойства изображаются:

osText — только текст;

osPlusMinusText — текст и пиктограммы PicturePlus и PictureMinus в зависимости от состояния узла. "Лист" не имеет значка;

osPictureText — текст и пиктограммы PictureOpen, PictureClosed и PictureLeaf в зависимости от состояния узла;

osPlusMinusPictureText — объединяет в себе два предыдущих стиля;

osTreeText — текст и специальные линии, иллюстрирующие связь между родительским и дочерними узлами;

osTreePictureText — объединяет в себе стили osTreeText и osPictureText. По умолчанию установлен стиль osTreePictureText;

На внешний вид дерева влияют и опции, содержащиеся в свойстве:

(Pb) property Options: TOutlineOptions;

TOutlineOption =- (ooDrawTreeRoot, ooDrawFocusRect, ooSCretchBitmaps) ;

TOutlineOptions =- set of TOutlineOption;

Это множество может содержать элементы:

ooDrawTreeRoot — задает соединение линией всех узлов верхнего уровня. В случае отсутствия опции каждый из них выглядит как вершина от­дельного дерева. Эта опция играет роль только для стилей osTreeText, osTreePictureText;

ooDrawFocusRect — задает выделение сфокусированного узла рамкой из точек;

ooStretchBitmaps — задает приведение размеров пиктограмм к размерам шрифта текста путем масштабирования. В противном случае либо из пиктограммы вырезается часть (если она больше), либо остается свободное место (если меньше).

Рисование дерева по умолчанию осуществляется системой, но может быть возложено и на программиста. Определяется это свойством:

(№) property Style: TOutlineType;

TOutlineType = (otStandard, otOwnerDraw) ;

Стиль osStandard подразумевает, что дта каждого узла будет изображено то, что предусмотрено стилем OutlineStyle. Для реализации стиля otOwnerDraw нужно нарисовать содержимое узла в обработчике события:

(Pb) property OnDrawItern: TDrawItemEvent;

TDrawItemEvent = procedure(ListBox: TListBox; Index: Integer;

Rect: TRect; State: TOwnerDrawState) of object;

Параметры:

Index — индекс узла;

Rect — отведенный ему прямоугольник;

State — множество, в которое могут входить состояния odSelected, odFocused.

Высота каждого узла постоянна и в этом случае определяется свойством:

(Pb) property ItemHeight: Integer;

Для рисования у компонента есть своя канва:

property Canvas: TCanvas ;

Установить ее можно только для объекта стиля osOwnerDraw; при osStandard канва игнорируется.

Обрамление компонента задается свойством:

(Pb) property BorderStyle: TBorderStyle;

Разобраться с применением этого компонента поможет пример OBJTREE. В нем по заранее заданному массиву компонентов ClassesSet выстраивается иерархическое дерево, в которое добавляются и все объекты-предки. Для примера были выбраны только 32 компонента, при желании можно включить и все остальные. Не забывайте при этом добавить содержащие их модули к тем, что содержатся в операторе uses. Когда вы перемещаете фокус по дереву, отображается имя объекта и имя модуля, в котором он описан. Для этого используется информация, возвращаемая недокументированным (пока?) мето­дом класса TObject.ClassInfo. Возвращаемая им структура описана в исходных текстах VCL.

Соседние файлы в папке Delphi