【问题标题】:Allowing keyboard input to a FireMonkey TEdit nested inside a FireMonkey TPopup允许对嵌套在 FireMonkey TPopup 内的 FireMonkey TEdit 进行键盘输入
【发布时间】:2014-01-20 08:08:30
【问题描述】:

我正在努力让 FireMonkey TEdit 嵌套在 FireMonkey TPopup 中以接收键盘输入。桌面和移动项目都会发生,尽管我对后者感兴趣:

  1. 创建一个新的 FMX 项目。

  2. 在表单中添加TButtonTPopup,在TPopup 中添加TEdit

  3. 将弹出窗口的Placement 属性设置为plCenter,将其PlacementTarget 设置为Button1

  4. 通过将弹出窗口的IsOpen 属性设置为True 来处理按钮的OnClick 事件。

  5. 运行项目,单击/点击按钮,然后尝试在编辑控件中输入文本。

有什么想法吗?正确的答案当然可能是:不支持键盘输入,但documentation 不支持。

【问题讨论】:

    标签: delphi firemonkey delphi-xe5


    【解决方案1】:

    有同样的问题,但修复了很少覆盖的行为。将表单更改为 TFormStyle.Normal 并处理 OnDeactivate 事件。

        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;
    

    【讨论】:

    • 感谢分享。几个月来,我一直在为这个问题寻找真正的解决方案。您的解决方案似乎部分有效。我有一个用作搜索框的 TEdit,我现在可以输入,但它不显示字符并且字母是不可见的。 (我有 TPopup + TPanel 和一个 TEdit 和 TListbox 是这个 TPanel 的子级)。当我使用退格键并且没有其他要删除的内容时,会发生 av。
    【解决方案2】:

    键盘输入似乎不适用于 TPopup。 一个简单的解决方案是使用 TForm 作为弹出表单:

    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.
    

    表单资源:

    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
    

    当然你可以改进这个简单的例子: 不要将 TEdit 放在此表单上,而是继承此表单并将编辑放在此处。 例如:

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

    改进 TfmPopup 的基类,增加一些功能,例如 TPopup: 例如。放置。 愿您可以在 TfmPopup 中使用从未显示的 TPopup 来使用 TPopup 的放置例程,而无需重写此代码。

    【讨论】:

      【解决方案3】:

      使用Popup1.popup(true) 而不是更改isOpen 属性

      【讨论】:

      • 谢谢 - 这适用于 Windows,但不幸的是在不支持无参数 ShowModal 的 Android 上引发异常。
      • 可能不需要此解决方案 - 因为弹出窗口是一个模态窗口,如果用户在外部单击则不会关闭。下面的解决方案可以作为真正的非模态弹出窗口。
      【解决方案4】:

      有类似这样的 TPopup 案例:

      但即使在悬停时 TEdit 会显示适当的输入光标,但单击它时弹出窗口会关闭。

      所以我使用以下内容:

      procedure TStoryItemOptions.actionChangeUrlActionExecute(Sender: TObject);
      begin
        TDialogServiceAsync.InputQuery('URL', ['URL'], [StoryItem.GetUrlAction], procedure(const AResult: TModalResult; const AValues: array of string)
          begin
          if (AResult = mrOk) then
            begin
            editUrlAction.Text := AValues[0]; //this will call "OnChangeTracking" handler
            //ShowPopup;
            end;
          end
        );
        ShowPopup;
      end;
      
      procedure TStoryItemOptions.editUrlActionChangeTracking(Sender: TObject);
      begin
        StoryItem.SetUrlAction(editUrlAction.Text);
      end;
      
      procedure TStoryItemOptions.editUrlActionMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
      begin
        actionChangeUrlAction.Execute;
      end;
      
      procedure TStoryItemOptions.ShowPopup;
      begin
        CheckCreatePopup;
      
        if Assigned(FPopup) then
          FPopup.IsOpen := true;
      end;
      

      请注意,我再次显示 Popup - 这会导致它仅在输入期间出现,这样用户就不会对显示的模态输入感到困惑。我还尝试在输入对话框显示的匿名方法的末尾添加 ShowPopup(请注意,Android 需要异步对话框,Android 的 Delphi 11 目前不支持同步对话框)以在按下 OK 后再次显示弹出窗口但没有不行。可能它在其他线程执行(并忽略),没有尝试从 UI 线程告诉它执行,或者尝试在超时后稍后执行它

      代码位于 http://github.com/zoomicon/READCOM_App 中的 StoryItemOptions 框架代码(仍在大力开发中)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-09-28
        • 2016-07-28
        • 2013-09-15
        • 2017-05-10
        • 1970-01-01
        • 2021-05-07
        • 2014-09-10
        相关资源
        最近更新 更多