我有一个从TCustomTreeView
派生的Treeview控件。
我在类中添加了一些自己的过程,比如添加节点。当在运行时调用这个过程时,我希望新添加的节点被选中,并且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
过程你可以覆盖它,它告诉我们什么时候控件被加载,但那只会在第一次运行时起作用。如果控件在运行时被用户隐藏(或者开始是不可见的),Cannot focus a disabled or invisible window
错误仍然会出现。
当不在调试器中运行时,执行此操作的脏方法是:
try
Selected := Node;
SetFocus;
except
end;
型
但这违背了目的,我讨厌以这种方式处理错误。
所以基本上我想知道是否有一种方法来确定控件是否可以接收焦点,以便我们可以将焦点设置为它?
1条答案
按热度按时间uqcuzwp81#
我不会回答你的问题,因为我认为你这样做是错的。
控件不应该在自身上调用
SetFocus
。我无法想象这是正确的行为。表单或应用程序或框架应该决定焦点。而不是控件。想象一下,当你有一个窗体有两个这样的控件时会发生什么?想象一下,使用键盘聚焦一个按钮,然后用空格键按下它。如果附加到按钮的操作调用了你的控件的方法,然后改变了焦点,你就违背了平台UI准则。你的控件现在给任何试图使用它的应用程序带来了严重的负担。