【问题标题】:How to delete all children from a TTreeViewItem?如何从 TTreeViewItem 中删除所有子项?
【发布时间】:2015-01-05 20:16:21
【问题描述】:

有没有办法从 TTreeViewItem 中删除所有子项?我试过DeleteChildren 但这会导致崩溃。

我认为是一个简单的问题,结果却产生了更多的问题。这就是我解释我正在尝试做的事情的原因。

我的应用程序尝试在 Delphi XE5 FMX 中生成目录树。我为此使用 TTreeView。它首先生成一个驱动器列表,所有这些驱动器都属于 TTreeView。当用户单击一个项目时,下面的目录将添加到该目录中,并且单击的 TTreeViewItem 会展开。当用户再次单击时,TTreeViewItem 会崩溃。这有一个警告:下次用户单击同一个 TTreeViewItem 时,目录列表将添加到现有目录中,见下图。为了防止这种情况,我想先清除当前列表。

当我尝试使用 TreeViewItem.DeleteChildren 从 TTreeViewItem 中删除子项时,我在另一个位置遇到异常,请参见下图。

至于一些问题:是的,我确定我只添加了 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 //

【问题讨论】:

  • “导致崩溃”你能详细说明一下吗?
  • @Jerry,你是对的。查看问题的更新。
  • 如果您删除了 TreeItem.Expand 中包含的所有内容,不确定您对它的期望。根据文档,DeleteChildren 删除所有孩子并将Children 设置为 nil。
  • 它在访问冲突中给你的地址是什么?它们比你想象的更重要 :-)
  • 首先,TMain.import_directory 是什么,您确定发件人实际上是 TTreeViewItem?

标签: delphi treeview firemonkey


【解决方案1】:

TreeItem.DeleteChildren 似乎删除了项目内容站点而不是子项目。 我建议使用这个:

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

【讨论】:

  • 就是这样!我做过几乎类似的事情:我对孩子们进行了手术,例如TreeItem.Children.CountTreeItem.Children.RemoveObject (i)' 这会产生非常奇怪的结果。非常感谢你!一切都按预期工作。
猜你喜欢
  • 1970-01-01
  • 2011-07-19
  • 2014-06-09
  • 1970-01-01
  • 2014-05-04
  • 2014-09-15
  • 1970-01-01
  • 1970-01-01
  • 2014-04-20
相关资源
最近更新 更多