2015-01-05 2 views
0

Есть ли способ удалить всех детей из TTreeViewItem? Я пробовал DeleteChildren, но это вызывает сбои.Как удалить всех детей из TTreeViewItem?

То, что я думал о том, что было простым вопросом, оказалось порождающим еще много вопросов. Вот почему я объясняю, что я пытаюсь сделать.

Мое приложение пытается сгенерировать дерево каталогов в Delphi XE5 FMX. Для этого я использую TTreeView. Он начинается с создания списка дисков, все из которых TTreeViewItem принадлежит TTreeView. Когда пользователь нажимает на элемент, каталоги, указанные ниже, добавляются в каталог, а TTreeViewItem нажимается на расширение. Когда пользователь снова нажимает выходы TTreeViewItem. У этого есть одно предостережение: в следующий раз, когда пользователь нажимает на тот же TTreeViewItem, список каталогов добавляется к существующим, см. Изображение ниже. Чтобы не допустить, чтобы я сначала очистил текущий список.

A list of duplicated directories

Когда я попытался удалить ребенок с помощью TreeViewItem.DeleteChildren из TTreeViewItem я получаю исключение в другом месте, см рисунок ниже.

Error message

Как на вопросы: да, я уверен, что только добавить TTreeViewItems и это единственное управление Поручаю событие OnClick (import_directory_click). Я добавил полный код и прокомментировал несущественные сведения.

Надеюсь, кто-то скажет мне, что эта функциональность уже существует (не удалось найти ее), но даже тогда я все равно хотел бы знать, как управлять TTreeView.

procedure TMain.import_initialize; 
    var 
    Item: TTreeViewItem; 
    drive: Char; 
    start: string; 
    begin 
    Directory_Tree.Clear; 

    {$IFDEF MSWINDOWS} 
    // When Windows, just present a list of all existing drives 
    for drive := 'C' to 'Z' do 
    begin 

    // A drive exists when its root directory exists 
     start := drive + ':\'; 
     if TDirectory.Exists (start) then import_add (start, Directory_Tree); 
    end; // for 
    {$ELSE} 
    // All other systems are unix systems, start with root. 

    drive := '/'; 
    start:= drive; 
    Item := import_add (TPath.GetPathRoot (start), DirectoryTree); 
    import_get_dirs (Item, start); 
    {$ENDIF} 
    start := TPath.GetSharedPicturesPath; 
    import_add (start, Directory_Tree); 
    if start <> TPath.GetPicturesPath 
     then import_add (TPath.GetPicturesPath, Directory_Tree); 
    // import_test_selection (''); 
    end; // import_initialize // 

    procedure TMain.import_directory_click (Sender: TObject); 
    var 
    TreeItem: TTreeViewItem; 
    obj: TFMXObject; 
    first_file: string; 
    begin 
    GridPanelLayout.Enabled := False; 
    if Sender <> nil then 
    begin 
     TreeItem := Sender as TTreeViewItem; 
     if TreeItem.IsExpanded then 
     begin 
      TreeItem.CollapseAll; 
     end else 
     begin 
      TreeItem.DeleteChildren; // <== this statement 
      import_get_dirs (TreeItem, TreeItem.Text); 
    { 
      first_file := find_first (TreeItem.Text, Selected_Images); 
      if first_file <> '' then 
      begin 
       Image.Bitmap.LoadFromFile (first_file); 
       GridPanelLayout.Enabled := True; 
      end; // if 
    } 
      TreeItem.Expand; // <== causes an exception over here 
     end; // if 
    end; // if 
    end; // import_directory_click // 

    procedure TMain.import_get_dirs (Start_Item: TTreeViewItem; start: string); 
    var 
    DirArray: TStringDynArray; 
    DirArraySize: Int32; 
    i: Int32; 
    begin 
    DirArray := TDirectory.GetDirectories (start); 
    DirArraySize := Length (DirArray); 
    for i := 0 to DirArraySize - 1 
     do import_add (DirArray [i], Start_Item); 
    end; // get_dirs // 

    function TMain.import_add (dir: string; owner: TControl): TTreeViewItem; 
    var 
    TreeItem: TTreeViewItem; 
    begin 
    TreeItem := TTreeViewItem.Create (owner); 
    TreeItem.text := dir; 
    TreeItem.OnClick := import_directory_click; 
    // TreeItem.Parent := owner; 
    owner.AddObject (TreeItem); 
    Result := TreeItem; 
    end; // import_add // 
+2

«вызывает сбои» Не могли бы вы рассказать? –

+0

@ Джерри, ты прав. См. Обновление вопроса. – Arnold

+5

Не знаете, как вы ожидаете «TreeItem.Expand», если вы удалили все, что он содержит. 'DeleteChildren' удаляет все дочерние элементы и устанавливает' Children' в nil, согласно документам. –

ответ

2

Похоже, что TreeItem.DeleteChildren удаляет объект контента, а не подэлементы. Предлагаю использовать:

for i := TreeItem.Count - 1 downto 0 do 
    TreeItem.RemoveObject(TreeItem.Items[i]); 
+0

Вот и все! Я сделал что-то почти похожее: я оперировал детей, например. 'TreeItem.Children.Count' и' TreeItem.Children.RemoveObject (i) ''Это дает довольно странные результаты.Большое спасибо! Все работает так, как ожидалось. – Arnold