Allowing keyboard input to a FireMonkey TEdit nested inside a FireMonkey TPopup

流过昼夜 提交于 2019-12-01 06:20:28

问题


I'm struggling to get a FireMonkey TEdit nested inside a FireMonkey TPopup to receive keyboard input. Happens both for desktop and mobile projects, though it's the latter I'm interested in:

  1. Create a new FMX project.

  2. Add a TButton and a TPopup to the form, and a TEdit to the TPopup.

  3. Set the popup's Placement property to plCenter and its PlacementTarget to Button1.

  4. Handle the button's OnClick event by setting the popup's IsOpen property to True.

  5. Run the project, click/tap the button, and try to enter text in the edit control.

Any ideas? The correct answer may of course be: keyboard input isn't supported, but the documentation doesn't say either way.


回答1:


Keyboard Input seems not to work on TPopup. An easy solution is to use a TForm as popup form:

unit Popup;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls, FMX.Edit;

type
  TfmPopup = class(TForm)
    Edit1: TEdit;
    Panel1: TPanel;
    procedure FormDeactivate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
  private
  protected
  public
  end;

var
  fmPopup: TfmPopup;

implementation

{$R *.fmx}

procedure TfmPopup.FormDeactivate(Sender: TObject);
begin
  Close;
end;

procedure TfmPopup.FormKeyDown(Sender: TObject; var Key: Word; var KeyChar: Char; Shift: TShiftState);
begin
  if Key = vkEscape then begin
    Close;
  end;
end;

end.

The form resources:

object fmPopup: TfmPopup
  Left = 0
  Top = 0
  BorderStyle = None
  Caption = 'Form1'
  ClientHeight = 94
  ClientWidth = 142
  FormFactor.Width = 320
  FormFactor.Height = 480
  FormFactor.Devices = [Desktop, iPhone, iPad]
  OnDeactivate = FormDeactivate
  OnKeyDown = FormKeyDown
  DesignerMobile = False
  DesignerWidth = 0
  DesignerHeight = 0
  DesignerDeviceName = ''
  DesignerOrientation = 0
  DesignerOSVersion = ''
  object Panel1: TPanel
    Align = Client
    Height = 94.000000000000000000
    Width = 142.000000000000000000
    TabOrder = 1
    object Edit1: TEdit
      Touch.InteractiveGestures = [LongTap, DoubleTap]
      TabOrder = 1
      Position.X = 20.000000000000000000
      Position.Y = 32.000000000000000000
      Width = 100.000000000000000000
      Height = 22.000000000000000000
    end
  end
end

Of course you can improve this simple example: Do not place the TEdit on this form but inherit this form and place the edit there. E.g.:

TfmMyPopup = class(TfmPopup)
  Edit1: TEdit;
private
protected
public
end;

Improve the base class of TfmPopup with some features like TPopup: E.g. placement. May you can use a never shown TPopup within TfmPopup to use the placement routines of the TPopup without rewriting this code.




回答2:


Had same problem, but fixed behavior with few overrides. Changed form to TFormStyle.Normal and handled OnDeactivate event.

    TPopup2 = class(TPopup)

    protected
      function CreatePopupForm: TFmxObject; override;
    end;

    TPopupForm2 = class(TCustomPopupForm)

    private
      procedure OnDeactivateEvent(Sender: TObject);
    public
      constructor CreateNew(AOwner: TComponent; Dummy: NativeInt = 0); override;
    end;

function TPopup2.CreatePopupForm: TFmxObject;
var
  NewStyle: TStyleBook;
  NewForm: TPanelForm;
begin
  NewForm := nil;
  try
    if not Assigned(StyleBook) and Assigned(Scene) then
      NewStyle := Scene.GetStyleBook
    else
      NewStyle := StyleBook;
    NewForm := TPopupForm2.Create(Self, NewStyle, PlacementTarget);
  except
    FreeAndNil(NewForm);
    Raise;
  end;
  Result := NewForm;
end;

constructor TPopupForm2.CreateNew(AOwner: TComponent; Dummy: NativeInt);
begin
  inherited;
  BeginUpdate;
  try
    FormStyle := TFormStyle.Normal;
    BorderStyle := TFmxFormBorderStyle.None;
    Fill.Kind := TBrushKind.None;
    Transparency := True;
    OnDeactivate := OnDeactivateEvent;
  finally
    EndUpdate;
  end;

end;

procedure TPopupForm2.OnDeactivateEvent(Sender: TObject);
begin
  Close;
end;



回答3:


use Popup1.popup(true) instead of changing the isOpen property



来源:https://stackoverflow.com/questions/20890373/allowing-keyboard-input-to-a-firemonkey-tedit-nested-inside-a-firemonkey-tpopup

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!