Форум: "Основная";
Текущий архив: 2006.10.15;
Скачать: [xml.tar.bz2];
Вниз
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;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 3.38 c