delphi 如何知道控件何时可以聚焦?

bq3bfh9z  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(132)

我有一个从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;


但这违背了目的,我讨厌以这种方式处理错误。
所以基本上我想知道是否有一种方法来确定控件是否可以接收焦点,以便我们可以将焦点设置为它?

uqcuzwp8

uqcuzwp81#

我不会回答你的问题,因为我认为你这样做是错的。
控件不应该在自身上调用SetFocus。我无法想象这是正确的行为。表单或应用程序或框架应该决定焦点。而不是控件。
想象一下,当你有一个窗体有两个这样的控件时会发生什么?想象一下,使用键盘聚焦一个按钮,然后用空格键按下它。如果附加到按钮的操作调用了你的控件的方法,然后改变了焦点,你就违背了平台UI准则。你的控件现在给任何试图使用它的应用程序带来了严重的负担。

相关问题