Сохранение данных узлов TTreeView при скрытии панели докинга в Delphi 2009
Вопрос разработчика, связанный с использованием компонента TTreeView в приложении Delphi 2009, заключается в необходимости сохранения данных узлов при скрытии панели докинга, на которой размещен TTreeView. Разработчик хочет использовать подкласс TTreeNode для упрощения приложения, но сталкивается с проблемой потери данных узлов при автоматическом скрытии панели.
Описание проблемы
При использовании подкласса TTreeNode для TTreeView, размещенного на панели докинга, возникает проблема сохранения данных узлов. Когда панель скрывается, обрабатываются события уничтожения окон, в результате чего инстансы подкласса TInfoTreeNode теряют свои данные. Это происходит потому, что при уничтожении окна, в котором размещен TTreeView, освобождаются дескрипторы, что приводит к потере состояния узлов.
Подход к решению
Разработчик предлагал использовать свойство Tag или Data каждого узла для хранения индекса в список, содержащий объекты с дополнительной информацией, или использовать приведение типов для хранения ссылок на объекты и доступ к ним напрямую. Однако, разработчик стремится избежать необходимости устанавливать свойство Data и создавать/уничтожать объекты данных таким образом, чтобы избежать утечек памяти.
Решение проблемы
Разработчик нашел решение, используя подкласс TTreeNode и обработку событий OnCreateNodeClass, OnDeletion и OnAddition компонента TTreeView. Создается запись TInfoTreeNodeMemory для хранения дополнительных данных узла и класс TInfoTreeNodeMemoryItemList для управления списком узлов.
В коде подкласса TInfoTreeNode создается свойство InfoTreeNodeMemory для доступа к данным узла. Класс TInfoTreeNodeMemoryItemList содержит список всех узлов и методы для обработки событий добавления и удаления узлов.
При добавлении узла в TTreeView, его свойство Data устанавливается в индекс, который используется для поиска соответствующих данных в списке. При удалении узла, соответствующие данные извлекаются из списка и сохраняются.
TInfoTreeNodeMemory=record
...
end;
TInfoTreeNode=class(TTreeNode)
private
m_rInfoTreeNodeMemory:TInfoTreeNodeMemory;
public
property InfoTreeNodeMemory:TInfoTreeNodeMemory read m_rInfoTreeNodeMemory write m_rInfoTreeNodeMemory;
end;
TInfoTreeNodeMemoryItemList=class
private
m_List:TList<TInfoTreeNodeMemory>;
public
constructor Create;
destructor Destroy; override;
procedure HandleOnDeletion(Node: TInfoTreeNode);
procedure HandleOnAddition(Node: TInfoTreeNode);
end;
TfraInfoTree = class(TFrame)
tvInfo: TTreeView;
procedure tvInfoCreateNodeClass(Sender: TCustomTreeView; var NodeClass: TTreeNodeClass);
procedure tvInfoDeletion(Sender: TObject; Node: TTreeNode);
procedure tvInfoAddition(Sender: TObject; Node: TTreeNode);
private
m_NodeMemory:TInfoTreeNodeMemoryItemList;
...
end;
procedure TfraInfoTree.tvInfoCreateNodeClass(Sender: TCustomTreeView; var NodeClass: TTreeNodeClass);
begin
NodeClass:=TInfoTreeNode;
end;
procedure TfraInfoTree.tvInfoDeletion(Sender: TObject; Node: TTreeNode);
begin
m_NodeMemory.HandleOnDeletion(TInfoTreeNode(Node));
end;
procedure TfraInfoTree.tvInfoAddition(Sender: TObject; Node: TTreeNode);
begin
m_NodeMemory.HandleOnAddition(TInfoTreeNode(Node));
end;
g_icTreeNodeNotInList=MAXINT;
procedure TInfoTreeNodeMemoryItemList.HandleOnDeletion(Node: TInfoTreeNode);
var
iPosition:integer;
begin
iPosition:=integer(Node.Data);
if iPosition=g_icTreeNodeNotInList then
raise Exception.Create('Node memory not found!')
else
m_List[iPosition]:=Node.InfoTreeNodeMemory;
end;
procedure TInfoTreeNodeMemoryItemList.HandleOnAddition(Node: TInfoTreeNode);
var
iPosition:integer;
begin
iPosition:=integer(Node.Data);
if iPosition=g_icTreeNodeNotInList then
begin
Node.Data:=pointer(m_List.Count);
m_List.Add(Node.InfoTreeNodeMemory);
end
else
Node.InfoTreeNodeMemory:=m_List[iPosition];
end;
Таким образом, разработчик смог сохранить данные узлов даже при скрытии панели докинга, используя подход с подклассом TTreeNode и управлением данными через обработку событий компонента TTreeView.
Заключение
При работе с TTreeView в Delphi 2009, особенно при использовании панели докинга, важно учитывать, что при скрытии панели данные узлов могут быть потеряны. Использование подкласса TTreeNode в сочетании с правильной обработкой событий позволяет сохранить необходимую информацию и избежать необходимости перезагрузки данных из базы при каждом отображении панели.
Разработчик в Delphi 2009 столкнулся с проблемой сохранения данных узлов `TTreeView` при скрытии панели докинга и нашел решение с использованием подкласса `TTreeNode` и управления событиями компонента.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.