如何从 TTreeViewItem 中删除所有子项?
How to delete all children from a TTreeViewItem?
有没有办法从 TTreeViewItem 中删除所有子项?我试过 DeleteChildren
但这会导致崩溃。
我以为是一个简单的问题,结果却产生了更多的问题。这就是为什么我解释我正在尝试做的事情。
我的应用程序试图在 Delphi XE5 FMX 中生成目录树。我为此使用 TTreeView。它首先生成一个驱动器列表,所有这些驱动器都属于 TTreeView 的 TTreeViewItem。当用户单击某个项目时,下面的目录将添加到目录中,并且单击的 TTreeViewItem 会展开。当用户再次单击时,TTreeViewItem 崩溃。这有一个警告:下次用户单击同一个 TTreeViewItem 时,目录列表将添加到现有目录中,请参见下图。为了防止这种情况,我想先清除当前列表。
当我尝试使用 TreeViewItem.DeleteChildren 从 TTreeViewItem 中删除子项时,我在另一个位置遇到异常,请参见下图。
关于一些问题:是的,我确定我只添加了 TTreeViewItems,这是我分配 OnClick 事件的唯一控件 (import_directory_click)。我已经添加了完整的代码并注释掉了 non-essentials 以确保。
我希望有人告诉我这个功能已经存在(找不到),但即便如此我仍然想知道如何管理 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 //
似乎 TreeItem.DeleteChildren 删除了项目内容站点而不是子项目。
我建议使用这个:
for i := TreeItem.Count - 1 downto 0 do
TreeItem.RemoveObject(TreeItem.Items[i]);
有没有办法从 TTreeViewItem 中删除所有子项?我试过 DeleteChildren
但这会导致崩溃。
我以为是一个简单的问题,结果却产生了更多的问题。这就是为什么我解释我正在尝试做的事情。
我的应用程序试图在 Delphi XE5 FMX 中生成目录树。我为此使用 TTreeView。它首先生成一个驱动器列表,所有这些驱动器都属于 TTreeView 的 TTreeViewItem。当用户单击某个项目时,下面的目录将添加到目录中,并且单击的 TTreeViewItem 会展开。当用户再次单击时,TTreeViewItem 崩溃。这有一个警告:下次用户单击同一个 TTreeViewItem 时,目录列表将添加到现有目录中,请参见下图。为了防止这种情况,我想先清除当前列表。
当我尝试使用 TreeViewItem.DeleteChildren 从 TTreeViewItem 中删除子项时,我在另一个位置遇到异常,请参见下图。
关于一些问题:是的,我确定我只添加了 TTreeViewItems,这是我分配 OnClick 事件的唯一控件 (import_directory_click)。我已经添加了完整的代码并注释掉了 non-essentials 以确保。
我希望有人告诉我这个功能已经存在(找不到),但即便如此我仍然想知道如何管理 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 //
似乎 TreeItem.DeleteChildren 删除了项目内容站点而不是子项目。 我建议使用这个:
for i := TreeItem.Count - 1 downto 0 do
TreeItem.RemoveObject(TreeItem.Items[i]);