当然,我忽略了一些如此明显和简单的东西,但我看不到它。
我有一个树视图,在运行时添加了节点,也可以删除它们。当我删除一个节点时,树中不再有一个选定的节点,HideSelection也被设置为False,但是当删除所选节点时,无论如何都没有区别,我猜是标准行为。
无论如何,为了减少重新聚焦到树视图所需的次数和输入,我希望在删除一个节点后自动重新选择树中的节点(如果删除大量节点,则会快速连续删除需要点击回到树视图上。)
所以我想说我有一棵这样的树:
这是我正在寻找的行为模式,使用以下方案作为示例:
Item1
后,可以选择Root
。Item2
后,可以选择Item6
。Item3
后,可以选择Item4
。Item4
后,可以选择Item5
。Item5
后,可以选择Item4
。Item5
,如果Item4
不存在则删除,则应选择Item3
。Item5
,如果在Item3
或Item4
不存在时删除,请选择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;
这是否是我再次完全误解情况并使任务变得不必要的困难,或者是否有很多工作要实施这种行为?
非常感谢提前。
答案 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;
请注意,当删除一个项目时,我无法按照您的逻辑来选择要选择的项目,主要是因为当删除节点时,所有子节点也会被删除。您可以调整以上内容以满足您的需求。