Delphi 我如何知道控件何时可以聚焦?
我有自己的Treeview控件,它来自Delphi 我如何知道控件何时可以聚焦?,delphi,delphi-xe,Delphi,Delphi Xe,我有自己的Treeview控件,它来自TCustomTreeView 我向类中添加了一些自己的过程,例如添加节点。在运行时调用此过程时,我希望选择新添加的节点,并聚焦Treeview,以便突出显示新节点 以下是摘录: procedure TMyTreeView.AddGroup(AName: string); var Node: TTreeNode; Obj: TGroup; procedure AddToTree; begin Obj := TGroup.Create
TCustomTreeView
我向类中添加了一些自己的过程,例如添加节点。在运行时调用此过程时,我希望选择新添加的节点,并聚焦Treeview,以便突出显示新节点
以下是摘录:
procedure TMyTreeView.AddGroup(AName: string);
var
Node: TTreeNode;
Obj: TGroup;
procedure AddToTree;
begin
Obj := TGroup.Create(AName);
FGroups.Add(Obj);
Node := Items.AddObject(Node, AName, Obj);
with Node do
begin
ImageIndex := 0;
SelectedIndex := 0;
end;
Selected := Node;
SetFocus;
end;
begin
Node := nil;
AddToTree;
end;
上述方法可行,但从表单OnCreate
事件调用时,我会遇到常见的错误消息:
无法聚焦已禁用或不可见的窗口
我知道您可以使用OnActivate
事件,或者根本不使用OnCreate
,这不会导致错误,但是任何其他可能使用该组件的人可能都没有意识到这一点
因此,我想知道是否有办法确定我的Treeview(或任何控件)是否能够接收焦点,然后我可以添加一些我自己的检查,比如:
if ControlIsFocusable then
begin
Selected := Node;
SetFocus;
end;
我知道有一个Loaded
过程可以重写,它告诉我们何时加载控件,但只有在第一次运行时才起作用。如果控件在运行时被用户隐藏(或开始时不可见),则无法聚焦禁用或不可见的窗口
错误仍将显示
当不在调试器中运行时,执行此操作的最糟糕方式是:
try
Selected := Node;
SetFocus;
except
end;
但这违背了目的,我讨厌用这种方式处理错误
所以基本上我想知道是否有一种方法可以确定控件是否可以接收焦点,以便我们可以将焦点设置为它?我不打算回答你提出的问题,因为我认为你做得不对 控件本身不应调用
SetFocus
。我无法想象在任何情况下,这种行为都是正确的。表单、应用程序或框架应确定焦点。不是控制
想象一下,当一个窗体有两个这样的控件时会发生什么?想象一下,使用键盘对焦一个按钮,然后用空格键按下。如果附加到按钮的操作调用了控件的方法,从而更改了焦点,那么您就违反了平台UI准则。您的控件现在给任何试图使用它的应用程序带来了沉重的负担。我不打算回答您提出的问题,因为我认为您这样做是错误的 控件本身不应调用
SetFocus
。我无法想象在任何情况下,这种行为都是正确的。表单、应用程序或框架应确定焦点。不是控制
想象一下,当一个窗体有两个这样的控件时会发生什么?想象一下,使用键盘对焦一个按钮,然后用空格键按下。如果附加到按钮的操作调用了控件的方法,从而更改了焦点,那么您就违反了平台UI准则。您的控件现在给任何试图使用它的应用程序带来了严重的负担。我认为您这样做是错误的。控件本身不应调用
SetFocus
。我无法想象在任何情况下,这种行为都是正确的。表单、应用程序或框架应确定焦点。不是控制。想象一下,当一个窗体有两个这样的控件时会发生什么?如果MyTreeView1.HandleAllocated和IsWindowVisible(MyTreeView1.Handle),那么您需要的是CanFocus@Keith-事实并非如此。@Blobby-不客气IsWindowVisible
反映控件的api级别窗口的实际可见性,而不是VCLvisible
声明的意图。例如,在隐藏的父控件中可以有一个可见的控件,当然你看不到它。这与Keith提到的CanFocus
差不多,表单本身是可见的,但实际上是不可见的(在OnCreate
中就是这样)<代码>显示
更符合实际可见性,但如果您感兴趣的是api对可见性的看法,那么询问api是最安全的选择。我认为您这样做是错误的。控件本身不应调用SetFocus
。我无法想象在任何情况下,这种行为都是正确的。表单、应用程序或框架应确定焦点。不是控制。想象一下,当一个窗体有两个这样的控件时会发生什么?如果MyTreeView1.HandleAllocated和IsWindowVisible(MyTreeView1.Handle),那么您需要的是CanFocus@Keith-事实并非如此。@Blobby-不客气IsWindowVisible
反映控件的api级别窗口的实际可见性,而不是VCLvisible
声明的意图。例如,在隐藏的父控件中可以有一个可见的控件,当然你看不到它。这与Keith提到的CanFocus
差不多,表单本身是可见的,但实际上是不可见的(在OnCreate
中就是这样)<代码>显示
更符合实际可见性,但如果您感兴趣的是api对可见性的看法,那么询问api是最安全的选择。好吧,我现在意识到这是一个错误。正如我之前评论的那样,我只使用一个控件实例进行测试,因此从未想到过使用多个控件的场景。现在你已经引起了我的注意,我可以看出我试图做的是错误的和不好的。所以我同意不回答我提出的问题,因为它现在基本上是无效的,只会试图解决一个本来不应该存在的问题。这么说来,解决方案就是删除SetFocus
行,如果用户需要突出显示节点,他们可以自己设置焦点。另外值得注意的是HideSelection
属性,设置为False至少表示选择了当前节点。好吧,我现在意识到这是一个错误。正如我之前评论的那样,我只测试了一个