创建可以很好地处理焦点的弹出窗口

问题描述 投票:0回答:1

我正在 FMX 应用程序中开发类似于 Microsoft Teams 的标记功能。

Teams 中的外观如下:

enter image description here

现在在我的版本中,我还想向弹出窗口添加编辑字段和其他内容。

我开始尝试使用

TPopup
,但问题是,如果您单击弹出窗口内的
TEdit
,弹出窗口将关闭。因此,我改用
TForm
并解决了该问题,但在使用
Show
显示表单后,我的备忘录不再具有焦点。

我想将注意力集中在备忘录上,除非我们单击弹出窗口内的编辑,在这种情况下,编辑应该获得焦点并且弹出窗口应该保持打开状态。如果我在弹出窗口外部单击,则弹出窗口应该关闭。

有办法解决这个问题吗?

delphi firemonkey delphi-12-athens
1个回答
0
投票

这应该有效。

主窗体单元

var MainForm:TMainForm;

implementation
{$R *.fmx}
uses PopupFormUnit;

procedure TMainForm.FormMouseDown(Sender:TObject; Button:TMouseButton; Shift:TShiftState; X,Y:Single);
begin
//If you click anywhere on the main form that doesn't take focus, this will hide the popup.
  PopupForm.Hide;
end;

procedure TMainForm.MemoClick(Sender:TObject);
//My trigger for testing purposes.  You do what you need to to trigger the popup
begin
  OpenPopup;
end;

procedure TMainForm.MemoExit(Sender:TObject);
begin
//If you click on any other focusable control on the main form, you want the popup to hide.
//See the note about the timer.
  PopupTimer.Enabled:=True;
end;

procedure TMainForm.OpenPopup;
begin
  PopupForm.Show;  //Show the popup
  Active:=True;    //Return the focus to the main form.
end;

procedure TMainForm.PopupTimerTimer(Sender:TObject);
begin
  PopupForm.Hide;            //Hide the popup
  PopupTimer.Enabled:=False; //And turn the timer off.
end;

end.

弹出表单单元

注意:将

PopupForm.FormStyle
设置为
StayOnTop

var
  PopupForm: TPopupForm;

implementation

{$R *.fmx}

uses MainFormUnit;

procedure TPopupForm.FormActivate(Sender:TObject);
begin
  //We want to keep the popup from showing, so cancel the timer.
  MainForm.PopupTimer.Enabled:=False;
end;

end.

定时器

当您单击弹出窗口时,它会被激活,但主窗体的备忘录会首先失去焦点。 因此,如果 TMainForm.MemoExit 直接隐藏弹出窗口,则弹出窗口将被隐藏。 因此,我们启动一个计时器,该计时器将在完成后隐藏弹出窗口。 为了避免在我们刚刚单击弹出窗口时隐藏它,我们

TPopupForm.FormActivate
取消了计时器,这样
仅在这种情况下
,弹出窗口仍然显示。 在其他情况下,弹出窗口会关闭。 弹出窗口激活会在备忘录失去焦点后立即发生,因此您不需要计时器的间隔很长。 我将其设置为 10(毫秒),这对我来说没问题。

我把定时器放在主窗体上,但是放在弹出窗体上应该没问题,这样就可以避免弹出窗体单元引用主窗体单元了。

© www.soinside.com 2019 - 2024. All rights reserved.