Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

TTreeNode [D7, XP]


mfender ©   (2006-06-28 15:48:00) 

Здравствуйте.
Создал потомка TTreeNode.
У него есть ещё несколько классов потомков.
Вобщем, иерархия такая: TTreeNode->ThsNode->ThsPartsNode.

ThsPartNode(TreeView1.Selected).ClassNameпоказывает, что это TTreeNode, а (TreeView1.Selected as ThsPartNode).ClassNameвообще ругается и говорит, что это - Invalid class typecast.

Я изначально догадывался, что это так. А как сделать, чтобы он мои классы принимал, как родные?


mfender   (2006-06-29 08:38:00) [1]


> TUser ©   (29.06.06 01:34) [16]
> > Так и сделал :)
>
> Имхо зря. Тебе передается нод, а ты его проверяй операцией
> is или проверкой поля ClassName

Так потому весь сыр-бор и разгорелся, что в OnCreateNodeClass невозможно узнать тип. Они там все - TTreeNode, что не создавай.


Плохиш   (2006-06-29 02:15:00) [2]


> TUser ©   (29.06.06 01:34) [16]
> > Так и сделал :)
>
> Имхо зря. Тебе передается нод, а ты его проверяй операцией
> is или проверкой поля ClassName

К сожалению, после беглого просмотра генокода, не было найдено возможности узнать в событии OnCreateNodeClass какой Нод был передан в функцию Add :-(
Если знаете такую возможность, то поделитесь, автор об этом и просит.


TUser   (2006-06-29 01:34:00) [3]

> Так и сделал :)

Имхо зря. Тебе передается нод, а ты его проверяй операцией is или проверкой поля ClassName


mfender   (2006-06-28 18:52:00) [4]


> Плохиш ©   (28.06.06 18:41) [13]

> На вскидку, заведи вспомогательную переменную и перед добавлением
> присваивай ей тот узел, относительно которого добавляешь.
>

Так и сделал :)
Спасибо за помощь!


mfender   (2006-06-28 18:52:00) [5]

Вобщем, решение я нашёл такое:

1. Сделал наследыша от TTreeView:

 ThsTreeView = class(TTreeView)
 private
   procedure CreateNodeClass(Sender: TCustomTreeView;
     var NodeClass: TTreeNodeClass);
 public
   FCreatedNode: TClass;
   constructor Create(AOwner: TComponent); override;
 end;

FCreatedNode - переменная, куда я буду складывать определение класса создаваемых узлов.

У общего для всех ThsNode в конструкторе я передаю в неё ClassType

constructor ThsNode.Create(AOwner: TTreeNodes);
begin
 inherited Create(AOwner);
 (AOwner.Owner as ThsTreeView).FCreatedNode := Self.ClassType;
end;


Ну, а там уже понимаю, как её зовут:

procedure ThsTreeView.CreateNodeClass(Sender: TCustomTreeView;
 var NodeClass: TTreeNodeClass);
begin
 NodeClass := TTreeNodeClass(FCreatedNode);
end;


Работает!


Плохиш   (2006-06-28 18:41:00) [6]


> mfender ©   (28.06.06 17:56) [11]

На вскидку, заведи вспомогательную переменную и перед добавлением присваивай ей тот узел, относительно которого добавляешь.


Stakan   (2006-06-28 18:30:00) [7]

Ничего не понял, что такое OnCreateNode, какой Node нужно получить . . .


mfender   (2006-06-28 17:56:00) [8]


> Stakan ©   (28.06.06 17:40) [10]
> if Noddy is ThsDomainNode then
> ...
> else if Noddy is ThsObjectNode then
> ...?

Так вот и я о том же: откуда мне взять эти самые "Noddy"? Ну нету их! По команде Add() дело передаётся сразу в OnCreateNode, а потом уже в Add(). И как получить того Node, который написан в Add(Node, '')?
Вот ведь в чём беда!


Stakan   (2006-06-28 17:40:00) [9]

if Noddy is ThsDomainNode then
...
else if Noddy is ThsObjectNode then
...
?


mfender   (2006-06-28 17:22:00) [10]


> TTreeNode или его потомка. Чесно говоря не понятно в чём
> проблема.

Проблема в том, что это могут быть разные классы. Может быть ThsPartNode, может быть ThsDomainNode, может быть ThsObjectNode etc. Но в OnCreateNode они все выглядят как TTreeNode. И как мне определить, кто из них кто?


Stakan   (2006-06-28 16:55:00) [11]


> Это понятно. Но function TTreeNodes.Add(Sibling:
> TTreeNode; const S: string): TTreeNode; подразумевает,
> что я передаю именно TTreeNode (это в пресловутом
> событии).

TTreeNode или его потомка. Чесно говоря не понятно в чём проблема.


ЕГыук   (2006-06-28 16:54:00) [12]


> что я передаю именно TTreeNode

или его наследника


mfender   (2006-06-28 16:45:00) [13]


> TUser ©   (28.06.06 16:36) [5]
>
> > Наверное буду в них ещё поле с именем класса (String)
> приделывать.
>
> ClassName

Вот не получается...
Наверху написано TTreeNodeClass = class of TTreeNode;
Это понятно. Но functionTTreeNodes.Add(Sibling: TTreeNode; constS: string): TTreeNode;подразумевает, что я передаю именно TTreeNode (это в пресловутом событии).

Так как же, всё-таки, определелить в OnCreateNode какой именно объект я создаю - ThsPartNode, или ещё какой-нибудь ThsXNode?

Прямо замкнутый круг какой-то... :(


TUser   (2006-06-28 16:36:00) [14]


> Наверное буду в них ещё поле с именем класса (String) приделывать.

ClassName


mfender   (2006-06-28 16:22:00) [15]


> Stakan ©   (28.06.06 16:17) [3]

Дада, я уже только что догадался :) Блин, как всё просто...!
Осталось только додуматься, какому ноду какой класс приписывать.
Наверное буду в них ещё поле с именем класса (String) приделывать.

Спасибо всем!


Stakan   (2006-06-28 16:17:00) [16]

procedure Form1....(Sender: TCustomTreeView; var NodeClass: TTreeNodeClass)
begin
 NodeClass := ThsPartNode;
end;


mfender   (2006-06-28 16:02:00) [17]


> Используй событие OnCreateNodeClass

Не совсем понял: как его можно использовать? К тому же, он и в нём - NodeClass.ClassName = TTreeNode, несмотря на то, что создавал я:

var Node: ThsPartNode;
begin
 Node := ThsPartNode.Create(TreeView1.Items);
 TreeView1.Items.Add(Node, 'root');


Плохиш   (2006-06-28 15:52:00) [18]


> А как сделать, чтобы он мои классы принимал, как родные?

Используй событие OnCreateNodeClass


Наверх

Титульная страница Поиск, карта сайта Написать письмо