Delphi FMX将焦点设置为特定控件,以便光标出现

Delphi FMX将焦点设置为特定控件,以便光标出现,delphi,firemonkey,Delphi,Firemonkey,我创建了一个新的FMX测试项目。添加了一个选项卡控件。使用关联菜单添加3个选项卡。在第三个选项卡中,添加了一个TEdit。向tabcontrol添加了OnChangeEvent处理程序。编码如下: procedure TForm1.TabControl1Change(Sender: TObject); begin if TabControl1.ActiveTab = TabItem3 then begin self.ActiveControl := Edit1; self

我创建了一个新的FMX测试项目。添加了一个选项卡控件。使用关联菜单添加3个选项卡。在第三个选项卡中,添加了一个TEdit。向tabcontrol添加了OnChangeEvent处理程序。编码如下:

procedure TForm1.TabControl1Change(Sender: TObject);
begin
  if TabControl1.ActiveTab = TabItem3 then
  begin
    self.ActiveControl := Edit1;
    self.Focused := Edit1;
    Edit1.SetFocus;
  end;
end;
正如你所看到的,我根据以前的VCL经验尝试了各种组合。输入/光标焦点不会按代码更改为Edit1。当然,在Win32上运行时,如果单击edit1,焦点矩形(我使用的是样式)现在显示为光标。(正如所料)在Android上。只有当我自己转移焦点时,VK才会出现


有没有办法以编程方式执行此操作,以便用户可以直接开始键入?(无需将焦点转移到TEdit本身)。

firemonkey框架禁止在某些事件中改变焦点

要更改焦点,请向表单发送延迟消息

这可以通过匿名线程完成:

procedure TForm1.TabControl1Change(Sender: TObject);
begin
  if TabControl1.ActiveTab = TabItem3 then
  begin
    TThread.CreateAnonymousThread(
      procedure
      begin
        TThread.Synchronize( nil,
          procedure
          begin
            Edit1.SetFocus;
          end
        );
      end
    ).Start;
  end;
end;

要使其更通用,请使用专用程序:

procedure DelayedSetFocus(control : TControl);
begin
  TThread.CreateAnonymousThread(
    procedure
    begin
      TThread.Synchronize( nil,
         procedure
         begin
           control.SetFocus;
         end
      );
    end
  ).Start;
end;
procedure DelayedSetFocus(control : TControl);
begin
  TThread.CreateAnonymousThread(
    procedure
    begin
      TThread.Synchronize( nil,
         procedure
         begin
           control.SetFocus;
         end
      );
    end
  ).Start;
end;

在XE6中,建议的代码仅在我在第二行过程之后添加begin时有效:

procedure DelayedSetFocus(control : TControl);
begin
  TThread.CreateAnonymousThread(
    procedure
    begin
      TThread.Synchronize( nil,
         procedure
         begin
           control.SetFocus;
         end
      );
    end
  ).Start;
end;
procedure DelayedSetFocus(control : TControl);
begin
  TThread.CreateAnonymousThread(
    procedure
    begin
      TThread.Synchronize( nil,
         procedure
         begin
           control.SetFocus;
         end
      );
    end
  ).Start;
end;

您可能无法在此
OnTabControl1Change
事件中更改焦点。设置一个标志,并在计时器中检查该标志,或向表单发送延迟消息。有趣的答案!我在TEdit上放置了一个OnCanFocus事件处理程序,它被调用。只是光标(和VK)没有显示。如果我要使用计时器,我可能会使用匿名线程…是的,我只是在为你写匿名线程!好的,既然你已经得到了它,请回答你的问题,让未来的读者看到。你不想在线程的执行部分包含一点延迟吗?类似睡眠(100)?我不确定是否需要延迟,因为它是同步的。我建议你试试。