如何删除treenode然后选择另一个以保持对树的关注?

时间:2013-09-15 18:28:54

标签: freepascal lazarus

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

我有一个树视图,在运行时添加了节点,也可以删除它们。当我删除一个节点时,树中不再有一个选定的节点,HideSelection也被设置为False,但是当删除所选节点时,无论如何都没有区别,我猜是标准行为。

无论如何,为了减少重新聚焦到树视图所需的次数和输入,我希望在删除一个节点后自动重新选择树中的节点(如果删除大量节点,则会快速连续删除需要点击回到树视图上。)

所以我想说我有一棵这样的树:

enter image description here

这是我正在寻找的行为模式,使用以下方案作为示例:

    删除Item1后,可以选择
  • Root
  • 删除Item2后,可以选择
  • Item6
  • 删除Item3后,可以选择
  • Item4
  • 删除Item4后,可以选择
  • Item5
  • 删除Item5后,可以选择
  • Item4
  • 可以选择
  • Item5,如果Item4不存在则删除,则应选择Item3
  • 可以选择
  • Item5,如果在Item3Item4不存在时删除,请选择Item2
  • 删除Item6后,可以选择
  • Item2
  • 删除Item7后,可以选择
  • Item6

我不断让Index超出界限和其他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;

这是否是我再次完全误解情况并使任务变得不必要的困难,或者是否有很多工作要实施这种行为?

非常感谢提前。

1 个答案:

答案 0 :(得分:4)

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

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

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;

请注意,当删除一个项目时,我无法按照您的逻辑来选择要选择的项目,主要是因为当删除节点时,所有子节点也会被删除。您可以调整以上内容以满足您的需求。