Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.10.15;
Скачать: CL | DM;

Вниз

TCustomTreeView.CreateWnd и DestroyWnd   Найти похожие ветки 

 
Ega23 ©   (2006-08-31 12:55) [0]

Можно ли как-то обойти сохранение-считывание нодов в поток?


 
Reindeer Moss Eater ©   (2006-08-31 12:58) [1]

так оба же виртуальные


 
Ega23 ©   (2006-08-31 13:05) [2]

Стоп. У меня потомок TCustomTreeView. Так вот я не хочу, чтобы в предке на DestroyWnd данные о нодах писАлись в поток, а на CreateWnd - читались.


 
Reindeer Moss Eater ©   (2006-08-31 13:13) [3]

копи & пасте оба метода в потомка и там закоментарить ненужные вызовы и не вызывать inherited от TCustomTreeView.

Но останется придумать как вызвать унаследованные методы от TWinContol"а


 
Ega23 ©   (2006-08-31 13:25) [4]


> Но останется придумать как вызвать унаследованные методы
> от TWinContol"а


В этом-то вся проблема...


 
MBo ©   (2006-08-31 13:35) [5]

В обоих методах загрузка-сохранение делается при выполнении if-ов. Можно сделать перед вызовом inherited так, чтобы условия не выполнялись (потом восстановить параметры)

P.S. Метод дедушки можно вызвать через TMethod


 
han_malign ©   (2006-08-31 13:36) [6]

эээ...
CreateWndRestores:= false;
- не катит?


 
MBo ©   (2006-08-31 13:39) [7]

Кстати, условие FCreateWndRestores имеет соответствующее property CreateWndRestores - так им и воспользоваться?


 
Ega23 ©   (2006-08-31 13:57) [8]

Сначала один вопрос, потом описание проблемы и способ реализации одного из решений, которое сейчас в курилке мозговым штурмом нашли.
Вопрос: нафига вообще это сохранение узлов и "карты раскрытия" в поток нужно?
Теперь, собственно, проблема и решение.
Делаю компонент TDBTreeView для отображения иерархических структур.
Унаследовался от TCustomTreeView, добавил свойства DataSource, KeyField, ParentField, DisplayField (Node.Text) и ещё по-мелочам.
Создал потомка TdataLink, создал класс TDBTreeViewItem

TDBTreeViewItem = class(TObject)
 private
   ............

 public
   constructor Create;
   destructor Destroy; override;

   function  isValid : boolean;

   property KeyFieldValue:Variant Read FKeyFieldValue Write FKeyFieldValue;
   property ParentKeyFieldValue:Variant Read FParentKeyFieldValue Write FParentKeyFieldValue;
   property DisplayFieldValue:String Read FDisplayFieldValue Write FDisplayFieldValue;
   property HintFieldValue : String Read FHintFieldValue Write FHintFieldValue;
   property ImageIndex:Integer Read FImageIndex Write FImageIndex;
   property Image:TBitmap Read FImage Write FImage;
   property Node:TTreeNode Read FNode Write set_Node;
end;


При TdataSet.Open через TTreeDataLink ловлю событие ActiveChanged. По нему:
1. Очищаю список TDBTreeViewItem"ов
2. Очищаю список Nod"ов.
3. Если Active=True - запускаю процедуру, которая в цикле по TDataSet.ActiveRecord строит список TDBTreeViewItem"ов, при этом заодно ищет минимальное значение ParenField (это будет root).
4. Запускаю рекурсивную процедуру создания узлов для этого списка, при этом при создании узла в Node.Data пишу указатель на соответствующий TDBTreeViewItem, а в нём в свойство Node пишу указатель на полученный Node. Таким образом получаются 2 синхронизированных списка.

Продолжение следует.


 
MBo ©   (2006-08-31 14:07) [9]

>Вопрос: нафига вообще это сохранение узлов и "карты раскрытия" в поток нужно?

Окно может пересоздаваться, например, при изменении Parent
А хранение узлов TreeView отдано Windows (как и для многих контролов, являющихся обертками над стандартными виндовыми, как, например, ListBox)


 
Ega23 ©   (2006-08-31 14:11) [10]

Поскольку у TCustomTreeView есть эти два дурных метода с сохранением и восстановлением узлов из потока, была выявлена проблема, что при Hide/Show парента, на котором лежит компонент, пропадала связка между  TDBTreeViewItem.Node и реальным узлом (обратная, между TTreeNode.Data и  TDBTreeViewItem сохранялась). Почему - понятно, узлы создаются заново и адрес их меняется.
Перекрыв метод TCustomTreeview.CreateWnd была сделана проверка связей и их восстановление от  TDBTreeViewItem к узлу.
Всё было хорошо до вчерашнего дня (а может и не всё хорошо, просто выплыло вчера...)
В силу обстоятельств, на событие OnActivate фрейма (собственное событие, фактически - BeforeActivate), где лежит данное дерево, был поставлен TDataSet.Close; TDataSet.Open;, т.е. обновление набора данных.
Таким образом, получилось следующее: на destroyWnd данные о нодах сохранились в стрим, на открытие запроса список узлов очистился (а он и так был пустым, т.к. они все в стриме), были созданы экземпляры TDBTreeViewItem и узлов из набора данных, а потом был восстановлен список узлов из стрима.

Продолжение следует.


 
Ega23 ©   (2006-08-31 14:18) [11]

Какое нашли решение:
На перекрытый DestroyWnd грохать список всех узлов, запомнив предварительно "карту раскрытия" (добавить в TDBTreeViewItem свойство Expanded), и уже после этого вызывать inherited DestroyWnd.
На перекрытый CreateWnd рекурсивно строить список узлов по имеющимуся списку TDBTreeViewItem"ов и восстанавливать карту раскрытия.


 
Reindeer Moss Eater ©   (2006-08-31 14:42) [12]

Мда. Интересно жить не запретишь, как говорится.
Есть же фриварный пакет в исходниках VirtualControls c тем самым dbaware три вью.


 
Ega23 ©   (2006-08-31 14:45) [13]


> Есть же фриварный пакет в исходниках VirtualControls c тем
> самым dbaware три вью.


Эта (моя) дрянь весьма специфична. Проще было самому писать, чем модифицировать другие.


 
Ega23 ©   (2006-08-31 14:46) [14]


> Reindeer Moss Eater ©   (31.08.06 14:42) [12]


Зато теперь я полностью "прочухал" всю эту борландовскую связку TDataSet->TDataSource->TDataLink...   :о)



Страницы: 1 вся ветка

Текущий архив: 2006.10.15;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.131 c
15-1158684060
GanibalLector
2006-09-19 20:41
2006.10.15
Джеф Раскин "Интерфейс"


15-1158905403
parasolka
2006-09-22 10:10
2006.10.15
jar архивы.


1-1157698439
Grid
2006-09-08 10:53
2006.10.15
dbgrid


15-1158922242
VitV
2006-09-22 14:50
2006.10.15
Необходимые библиотеки для VB6


1-1157525175
lessard
2006-09-06 10:46
2006.10.15
Как быстро скопировать 500 маленьких файлов