Статья: Предотвращение повторного открытия узлов в TreeList в Delphi
Введение в проблему
Работая с компонентом TreeList в Delphi, разработчики часто сталкиваются с необходимостью управления множественными узлами, каждый из которых имеет уникальный идентификатор. В ситуации, когда пользователю разрешено открывать несколько узлов одновременно, возникает задача предотвращения повторного открытия одного и того же узла. Это может быть важно для оптимизации производительности приложения и удобства работы пользователя.
В приведенном примере создается форма, связанная с уникальным идентификатором узла TreeList. Однако, чтобы избежать создания дубликатов форм с одинаковыми идентификаторами, можно использовать простой динамический массив для хранения соответствия между идентификаторами TreeList и HWND форм. При нахождении совпадения идентификатора в списке, открывается уже созданная форма, приводящаяся в состояние переднего плана.
Альтернативный подход
Исходя из замечаний, можно предложить упрощенный подход без создания нового массива. Достаточно пройти по всем формам, чтобы проверить, не открыта ли уже форма с определенным идентификатором. Если форма с нужным идентификатором уже существует, она будет показана, в противном случае будет создана новая форма.
for i := 0 to Screen.FormCount-1 do
begin
if Screen.Forms[i] is TChapter then
if (Screen.Forms[i] as TChapter).FID = qryTreeID.Value then
begin
(Screen.Forms[i] as TChapter).BringToFront;
Exit;
end;
end;
Подтвержденный ответ
Для более элегантного решения можно использовать TDictionary для хранения соответствия между идентификаторами и объектами форм. Это позволит избежать необходимости работы с HWND, который не является постоянным в течение всего жизненного цикла формы.
Пример использования TDictionary:
var
Chapters: TDictionary<Integer, TChapter> = nil;
procedure ChapterDestroyed(Sender: TObject);
begin
if Chapters <> nil then
Chapters.Remove(TChapter(Sender).FID);
end;
function FindChapterByID(ID: Integer): TChapter;
begin
// Поиск формы по идентификатору
if not Chapters.TryGetValue(ID, Result) then
Result := nil;
end;
function CreateChapter(ID: Integer): TChapter;
begin
Result := TChapter.Create(nil);
try
Result.FID := ID;
Result.Caption := 'Форма ' + ID.ToString;
Result.OnDestroy := ChapterDestroyed;
Chapters.Add(ID, Result);
except
Result.Free;
raise;
end;
end;
function ShowChapterByID(ID: Integer): TChapter;
begin
Result := FindChapterByID(ID);
if Result = nil then
Result := CreateChapter(ID);
Result.Show;
end;
initialization
Chapters := TDictionary<Integer, TChapter>.Create;
finalization
Chapters.Free;
При вызове функции ShowChapterByID с уникальным идентификатором узла, если форма уже существует, она будет активирована, в противном случае будет создана новая.
Chapter := ShowChapterByID(qryTreeID.Value);
Заключение
Использование TDictionary для управления состоянием форм является эффективным способом предотвращения повторного открытия узлов в TreeList, что повышает удобство использования и производительность приложений на Delphi.
Статья описывает проблематику повторного открытия узлов в компоненте TreeList в Delphi и предлагает решения для её устранения.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS