1

当然,我在这里忽略了一些如此明显和简单的东西,但我就是看不到它。

我有一个树视图,节点在运行时添加到它,也可以删除。当我删除一个节点时,树中不再有一个选定的节点,HideSelection 也设置为 False 但这不会有任何区别,因为选定的节点被删除,我猜是标准行为。

无论如何,为了减少需要重新关注树视图的次数和输入,我想在删除一个节点后自动重新选择树中的一个节点(如果连续快速删除大量节点特别有用,因为它消除了单击的需要回到树视图)。

所以假设我有一棵这样的树:

在此处输入图像描述

这是我正在寻找的行为模式,以以下场景为例:

  • Item1可以选择,当删除Root成为选择。
  • Item2可以选择,当删除Item6成为选择。
  • Item3可以选择,当删除Item4成为选择。
  • Item4可以选择,当删除Item5成为选择。
  • Item5可以选择,当删除Item4成为选择。
  • Item5可以选择,如果Item4不存在则删除,Item3则应选择。
  • Item5可以选择,当删除时,如果Item3Item4不存在,选择Item2.
  • Item6可以选择,当删除Item2成为选择。
  • Item7可以选择,当删除Item6成为选择。

我不断让索引越界和其他 AV 错误(在 Lazarus 中),这甚至没有达到检查当前选定节点在树中的位置的地步。

就目前而言,在我的删除事件中,我有这个:

procedure TMainForm.actDeleteExecute(Sender: TObject);
var  
  SelNode: TTreeNode;
begin
  if TreeView1.Selected <> nil then
  begin
    SelNode := TreeView1.Selected;

    TreeView1.Selected.Delete;
    TreeView1.SetFocus;
    //ShowMessage(SelNode.GetPrev.Text);  
    TreeView1.Selected.Index := SelNode.Index; 
  end;
end;

这是我再次完全误解情况并使任务变得不必要的困难的情况,还是实施这种行为涉及大量工作?

提前谢谢了。

4

1 回答 1

4

您的错误是访问已删除的节点以获取其索引:SelNode在您的示例中。它导致了AV。

假设您的问题是关于 Lazarus 的 TreeView 控件(如问题中所述),您可以按照 Kobik 在评论中的建议,在删除项目之前找到要选择的节点。或者,我觉得更简单,您可以OnDeletion在 TreeView 事件中实现您的逻辑。此事件在项目实际销毁之前触发。

procedure TForm1.actDeleteExecute(Sender: TObject);
begin
  if Assigned(TreeView1.Selected) then begin
    TreeView1.Selected.Delete;
    TreeView1.SetFocus;
  end;
end;

procedure TForm1.TreeView1Deletion(Sender: TObject; Node: TTreeNode);
begin
  if Assigned(TreeView1.Selected.GetPrevSibling) then
    TreeView1.Selected := TreeView1.Selected.GetPrevSibling
  else if Assigned(TreeView1.Selected.GetNextSibling) then
    TreeView1.Selected := TreeView1.Selected.GetNextSibling
  else if Assigned(TreeView1.Selected.GetPrev) then
    TreeView1.Selected := TreeView1.Selected.GetPrev
  else
    TreeView1.Selected := TreeView1.Selected.GetNext; // can be nil
end;

请注意,我无法遵循您的逻辑,即在删除一个项目时选择哪个项目,主要是因为当一个节点被删除时,它的所有子节点也会被删除。您可以根据自己的需要调整上述内容。

于 2013-09-15T20:16:12.933 回答