100 компонентов общего назначения библиотеки Delphi5

       

Окно редактора узлов дерева компонента TreeView


Кнопка New Item (новый узел) позволяет добавить в дерево новый узел. Он будет расположен на том же уровне, на котором расположен узел, выделенный курсором в момент щелчка на кнопке New Item.

Кнопка New SubItem (новый дочерний узел) позволяет добавить в дерево дочерний узел. Он будет расположен на уровень ниже уровня того узла, который выделен курсором в момент щелчка на кнопке New SubItem.

Кнопка Delete (удалить) удаляет выделенный узел дерева. Кнопка Load позволяет загрузить структуру дерева из файла. Файл, хранящий структуру дерева — это обычный текстовый файл, содержащий тексты узлов. Уровни узлов обозначаются отступами. Например, файл дерева, изображенного на Рисунок 3.18 и 3.20, может иметь вид: производство цех 1 цех 2 цех 3 управление администрация бухгалтерия

Для каждого нового узла дерева можно указать ряд свойств в панели Item Properties окна на Рисунок 3.20. Это прежде всего свойство Text — надпись, появляющаяся в дереве около данного узла. Свойства Image Index и Selected Index определяют индекс пиктограммы, отображаемой для узла, который соответственно не выделен и выделен пользователем в данный момент. Эти индексы соответствуют списку изображений, хранящихся в отдельном компоненте ImageList (см. ). Указание на этот компонент вы можете задать в свойстве Images компонента TreeView. Индексы начинаются с 0. Если вы укажете индекс -1 (значение по умолчанию), пиктограммы изображаться не будут. Последнее свойство — State Index в панели Item Properties позволяет добавить вторую пиктограмму в данный узел, не зависящую от состояния узла. Подобная пиктограмма может просто служить дополнителъной характеристикой узла. Индекс, указываемый как State Index, соответствует списку изображений, хранящихся в отдельном компоненте ImageList, указанном в свойстве StateImages компонента TreeView.

Мы рассмотрели формирование дерева в процессе проектирования. Однако, дерево можно формировать или перестраивать и во время выполнения приложения. Для этого служит ряд методов объектов типа TTreeNodes. Следующие методы позволяют вставлять в дерево новые узлы:

function Add(Node: TTreeNode; const S: string): TTreeNode;Добавляет новый узел с текстом S как последний узел уровня, на котором расположен Node. function AddFirst(Node: TTreeNode; const S: string): TTreeNode;Вставляет новый узел с текстом S как первый из узлов уровня, на котором находится Node. Индексы последующих узлов увеличиваются на 1. function Insert (Node: TTreeNode; const S: string): TTreeNode;Вставляет новый узел с текстом S сразу после узла Node на тот же уровень. Индексы последующих узлов увеличиваются на 1. function AddChild(Node: TTreeNode; const S: string): TTreeNode;Добавляет узел с текстом S как последний дочерний узла Node. function AddChildFirst(Node: TTreeNode; const S: string); TTreeNode;Вставляет новый узел с текстом S как первый из дочерних узлов узла Node. Индексы последующих узлов увеличиваются на 1.

Каждый из этих методов возвращает вставленный узел. Ниже в качестве примера приведен код, формирующий то же дерево, которое вы можете видеть на Рисунок 3.18 и 3.20. TreeView1.Items.Clear; // очистка списка // добавление корневого узла 'производство' (индекс 0) TreeView1.Items.Add(nil, 'производство'); {добавление дочерних узлов 'цех 1' — 'цех 3' (индексы 1 - 3)} TreeView1.Items.AddChild(TreeView1.Items.Item[0], 'цех 1'); TreeView1.Items.AddChild(TreeViewl.Items.Item[0], 'цех 2'); TreeView1.Items.AddChild(TreeView1.Items.Item[0], 'цех 3'); {добавление корневого узла 'управление' после узла 'производство' (индекс 4) } TreeView1.Items.Add(TreeView1.Items.Item[0], 'управление'); {добавление дочерних узлов 'администрация' и 'бухгалтерия' узла 'управление' } TreeView1.Items.AddChild(TreeView1.Items.Item[4], 'администрация'); TreeView1.Items.AddChild(TreeView1.Items.Item[4], 'бухгалтерия');

Дерево может быть сколь угодно разветвленным. Например, следующие операторы добавляют дочерние узлы «бригада 1» и «бригада 2» в сформированный ранее узел «цех 1»: TreeView1.Items.AddChild(TreeView1.Items.Item[1], 'бригада 1'); TreeView1.Items.AddChild(TreeView1.Items.Item[l], 'бригада 2');

Текст, связанный с некоторым узлом, можно найти с помощью его свойства Text. Например, TreeView1.Items.Item[1].Text — это надпись «цех 1».

С каждым узлом может быть связан некоторый объект. Добавление таких узлов осуществляется методами AddObject, AddObjectFirst, InsertObject, AddChildObject, AddChildObjectFirst, аналогичными приведенным выше, но содержащими в качестве параметра еще указатель на объект:

function AddObject(Node: TTreeNode; const S: string; Ptr: Pointer): TreeNode;Добавляет новый узел с текстом S и объектом Ptr как последний узел уровня, на котором расположен Node. function AddObjectFirst(Node: TTreeNode; const S: string; Ptr: Pointer): TTreeNode;Вставляет новый узел с текстом S и объектом Ptr как первый из узлов уровня, на котором находится Node. Индексы последующих узлов увеличиваются на 1. function InsertObject(Node: TTreeNode; const S: string; Ptr: Pointer): TTreeNode; Вставляет новый узел с текстом S и объектом Ptr сразу после узла Node на тот же уровень. Индексы последующих узлов увеличиваются на 1. function AddChildObject(Node: TTreeNode; const S: string; Ptr: Pointer): TTreeNode;Добавляет узел с текстом S и объектом Ptr как последний дочерний узла Node. function AddChildObjectFirst(Node: TTreeNode; const S: siring; Ptr: Pointer): TTreeNode;Вставляет новый узел с текстом S и объектом Ptr как первый из дочерних узлов узла Node. Индексы последующих узлов увеличиваются на 1.

Объект, связанный с некоторым узлом, можно найти с помощью его свойства Data. Например, TreeView1.Items.Item[1].Data.

Для удаления узлов имеется два метода: Clear, очищающий все дерево, и Delete(Node: TTreeNode), удаляющий указанный узел Node и все его узлы — потомки. Например, оператор TreeView1.Items.Clear; удалит в нашем примере все узлы, а оператор TreeView1.Items.Delete(TreeView1.Items.Item[1]); удалит узел «цех 1» и его дочерние узлы (если они имеются).

При удалении узлов, связанных с объектами, сами эти объекты не удаляются.

Реорганизация дерева, связанная с созданием или удалением многих узлов, может вызывать неприятное мерцание изображения. Избежать этого можно с помощью методов BeginUpdate и EndUpdate. Первый из них запрещает перерисовку дерева, а второй — разрешает. Таким образом, изменение структуры дерева может осуществляться по следующей схеме: TreeView1.Items.BeginUpdate; <операторы изменения дерева> TreeView1.Items.EndUpdate;

Если метод BeginUpdate применен подряд несколько раз, то перерисовка дерева произойдет только после того, как столько же раз будет применен метод EndUpdate.

Среди свойств узлов следует отметить Count — число узлов, управляемых данным, т.е. дочерних узлов, их дочерних узлов и т.п. Если значение Count узла равно нулю, значит у узла нет дочерних узлов, т.е. он является листом дерева.

Вернемся к свойствам компонента TreeView. Важным свойством компонента TreeView является Selected. Это свойство указывает узел, который выделен пользователем. Пользуясь этим свойством можно запрограммировать операции, которые надо выполнить для выбранного пользователем узла. Если ни один узел не выбран, значение Selected равно nil. При выделении пользователем нового узла происходят события OnChanging (перед изменением выделения). В обработчик события передаются параметры Node: TTreeNode — узел, который выделен в данный момент, и var AllowChange: Boolean — разрешение на перенос выделения. Если в обработчике задать AllowChange = false, то переключение выделения не произойдет.

У компонента TreeView имеется свойство RightClickSelect, разрешающее (при значении равном true) выделение узла щелчком как левой, так и правой кнопкой мыши.

Ряд событий компонента TreeView связан с развертыванием и свертыванием узлов. При развертывании узла происходят события OnExpanding (перед развертыванием) и OnExpanded (после развертывания). В обработчики обоих событий передается параметр Node: TTreeNode — развертываемый узел. Кроме того в обработчик OnExpanding передается параметр var AllowExpansion: Boolean, который можно задать равным false, если желательно запретить развертывание. При свертывании узла происходят события OnCollapsing (перед свертыванием) и OnCollapsed (после свертывания). Так же, как и в событиях, связанных с развертыванием, в обработчики передается параметр Node: TTreeNode — свертываемый узел, а в обработчик OnCollapsing дополнительно передается параметр var AllowCollapse: Boolean, разрешающий или запрещающий свертывание.

Свойство ReadOnly компонента TreeView позволяет запретить пользователю редактировать отображаемые данные. Если редактирование разрешено, то при редактировании возникают события OnEditing и OnEdited, аналогичные рассмотренным ранее (в обработчике OnEditing параметр var AllowEdit: Boolean позволяет запретить редактирование).

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

Свойство SortType позволяет автоматически сортировать ветви и узлы дерева. По умолчанию это свойство равно stNone, что означает, что дерево не сортируется. Если установить SortType равным stText, то узлы будут автоматически сортироваться по алфавиту. Возможно также проводить сортировку по связанным с узлами объектам Data (значение SortType равно stData), одновременно по тексту и объектам Data (значение SortType равно stBoth) или любым иным способом. Для использования этих возможностей сортировки надо написать обработчик события OnСompare, в который передаются, в частности, параметры Node1 и Node2 — сравниваемые узлы, и по ссылке передается целый параметр Compare, в который надо заносить результат сравнения: отрицательное число, если узел Node1 должен располагаться ранее Node2, 0, если эти узлы считаются эквивалентными, и положительное число, если узел Node1 должен располагаться в дереве после Node2. Например, следующий оператор в обработчике события OnCompare обеспечивает обратный алфавитный порядок расположения узлов: Compare := - AnsiCompareText(Node1.Text, Node2.Text);

События OnCompare наступают после задания любого значения SortType, отличного от stNone, и при изменении пользователем свойств узла (например, при редактировании им надписи узла), если значение SortType не равно stNone. После сортировки первоначальная последовательность узлов в дереве теряется. Поэтому последующее задание SortType = stNone не восстанавливает начальное расположение узлов, но исключает дальнейшую генерацию событий OnCompare, т.е. автоматическую перестановку узлов, например, при редактировании их надписей. Если же требуется изменить характер сортировки или провести сортировку с учетом новых созданных узлов, то надо сначала задать значение SortType = stNone, а затем задать любое значение SortType, отличное от stNone. При этом будут сгенерированы новые обращения к обработчику событий OnCompare.

Имеются и другие возможности сортировки. Например, метод AlphaSort обеспечивает алфавитную последовательность узлов независимо от значения SortType, но при отсутствии обработчика событий OnCompare (если обработчик есть, то при выполнении метода AlphaSort происходит обращение к этому обработчику). Отличие метода AlphaSort от задания значения SortType = stText заключается в том, что изменение надписей узлов приводит к автоматической пересортировке дерева только при SortType = stText.

Мы рассмотрели основные возможности компонента TreeView. Компонент Outline похож на него. Структура дерева тоже содержится в свойстве Items и доступ к отдельным узлам также осуществляется через этот индексный список узлов. Но индексы начинаются с 1. Например, Outline1.Items[1] — это узел дерева с индексом 1 (первый узел дерева). Свойство Items имеет тип TOutlineNode. Его свойства и методы отличаются от свойств и методов типа узлов в TreeView. И заполняется структура дерева иначе: через свойство Lines типа TStrings. Редактор этого свойства можно вызвать, щелкнув на кнопке с многоточием около свойства Lines в окне Инспектора Объектов. Вы попадете в окно, в котором можете записать тексты всех узлов, делая отступы, чтобы выделить уровни узлов. Текст должен выглядеть так, как выше описывалось представление структуры в текстовом файле.

Пиктограммы, сопровождающие изображения узлов, задаются параметрами PictureOpen (пиктограмма развернутого узла), PictureClosed (пиктограмма свернутого узла), PictureMinus (пиктограмма символа «-» около развернутого узла, имеющего наследников), PicturePlus (пиктограмма символа «+» узла, имеющего наследников, но не развернутого), PictureLeaf (пиктограмма узла, не имеющего наследников — листа дерева). Основное отличие пиктограмм компонента Outline заключается в том, что они одинаковы для всех узлов одного типа, тогда как в TreeView можно задавать пиктограммы индивидуально для каждого узла.

Программно изменять структуру дерева можно с помощью методов Add, AddObject (добавление узла в дерево), Insert, InsertObject (вставка узла в заданную позицию), AddChild, AddChildObject (вставка дочернего узла), Delete (удаление узла).

Индекс выделенного пользователем узла можно определить через свойство SelectedItem. Если SelectedItem = 0, значит ни один узел не выделен. Текст выделенного узла определяется свойством Text: например, OutLine1.Items[Outline1.SelectedItem].Text

Впрочем, тот же самый текст даст и выражение OutLine1.Lines[Outline1.SelectedItem-1]

В заключение коротко рассмотрим компонент ListView. Он позволяет отображать в стиле Windows 95/98 данные в виде списков, таблиц, крупных и мелких пиктограмм. С подобным отображением все вы сталкиваетесь, раскрывая папки Windows.

Стиль отображения информации определяется свойством ViewStyle, которое может устанавливаться в процессе проектирования или программно во время выполнения. Свойство может принимать значения: vsIcon — крупные значки, vsSmallIcon — мелкие значки, vsList — список, vsReport — таблица. Что означает каждое из этих значений вы можете посмотреть в любой папке Windows на рабочем столе.

Содержание раздела