我有一个类型为TVirtualStringTree
(以下简称VST
)的组件。它的节点以列表形式呈现,即所有节点都在同一级别上。我希望在删除节点后更改焦点(使用DeleteNode
方法),我使用了OnFreeNode
事件:
procedure TMyForm.VSTFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var
NewFocus: PVirtualNode;
begin
NewFocus := VST.GetNext(Node);
if not Assigned(newFocus) then
NewFocus := VST.GetPrevious(Node);
if Assigned(NewFocus) then
begin
VST.FocusedNode := NewFocus;
VST.Selected[NewFocus] := True
end;
end;
我希望这个改变能够引起一些反应,例如设置按钮的Enabled
属性:
procedure TMyForm.VSTFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex);
begin
btn1.Enabled := Assigned(Node);
end;
但是这种解决方案存在一些问题。例如,当我使用Cancel按钮关闭表单时(该表单是使用ShowModal
方法打开的),节点被释放,VSTFocusChanged
被触发,后者因为空按钮而抛出异常。当然,我可以检查按钮是否已分配,但是否有更优雅的解决方案在删除节点后更改焦点而不会产生这种不希望的效果(以及其他不希望的效果)?
ButtonDeleteNode
可能已经在OnStructureChange
中被释放。因此,我反对使用此事件来更新“操作”。您需要使用一些标志,以便可以退出此事件。 - kobikOnUpdate
操作事件。从那里更新操作是安全的(但访问“外部”控件不安全)。 - Victoria