tabcontrol中的Delphi firemonkey tabstop问题

时间:2014-02-14 15:08:36

标签: delphi firemonkey delphi-xe5

我正在为Windows平台的Delphi XE5 Update 2编写Firemonkey HD程序。 我有一个tabcontrol,表格上有一个tabitem,tabitem中有一些编辑框。我有相应的taborder设置(0,1,2,..),当我进入Edit1并按Tab键时,Edit1失去焦点但Edit2没有得到焦点。

我尝试将编辑框放在主窗体和面板中,然后它们正常工作,当我在edit1并点击选项卡时,它会转到edit2,依此类推,但在tabcontrol中的tabitem却没有。

有没有人知道这方面的工作或者我错过的设置?

感谢您的帮助

5 个答案:

答案 0 :(得分:2)

以下是问题的实际修复,我在http://vldgeorgiev.wordpress.com/2014/04/01/delphi-tab-key-and-taborder-not-working

中也有描述

它位于FMX.TabControl.pas单位的TTabItem的来源中 有一个名为TTabItem.DoAddObject

的重写方法
procedure TTabItem.DoAddObject(const AObject: TFmxObject);
var
  ControlTmp: TControl;
begin
  if Assigned(FContent) and not AObject.Equals(FContent) and not AObject.Equals(ResourceLink) then
  begin
    FContent.AddObject(AObject);
...
end;

虽然它应该是

procedure TTabItem.DoAddObject(const AObject: TFmxObject);
var
  ControlTmp: TControl;
begin
  if Assigned(FContent) and not AObject.Equals(FContent) and not AObject.Equals(ResourceLink) then
  begin
    FContent.AddObject(AObject);
    AddToTabList(AObject);       // This line is missing in the original source
...
end;

问题在于,当表单KeyDown方法处理Tab键时,它会调用AdvanceTabFocus方法,该方法会检查FTabList是否有任何子组件。由于TTabItem的原始DoAddObject方法缺少一行,因此它从未将子控件添加到该列表中,因此AdvanceTabFocus方法无法找到下一个控件。相反,它将焦点设置为表单上的第一个控件。

要使用此修复程序,请复制项目文件旁边的修改后的FMX.TabControl.pas单元,或者编译DCU并将它们放在Delphi安装文件夹的Lib ...子文件夹中。如果你没有消息来源,那你就不幸了。

顺便说一下,设置TabOrder数字并不总是足够的。您必须右键单击并使用" Tab顺序..."甚至在表单文本中手动重新排序控件(使用Alt-F12)

答案 1 :(得分:1)

这是一个已知的错误: http://qc.embarcadero.com/wc/qcmain.aspx?d=117380

看起来XE6可能已修复。

您可以使用Control.SetFocus手动设置焦点,但是您必须自己为每个控件设置焦点。您可以设置OnKeyUp事件并查看是否按下了标签(VK_TAB或9),以及是否确实将焦点设置为下一个控件。

答案 2 :(得分:1)

我以一种非常简单的方式解决了这个问题。 我将表单的高度更改为2000并将字段插入到我的滚动框中。 然后我将表格的高度恢复为原始高度。 根据我的理解,当组件位于滚动框的可见区域之外时,firemonkey会丢失。但如果表单的高度较大,则滚动框会认为一切都是可见的并且有效。

答案 3 :(得分:0)

我的申请中遇到了同样的问题,所以我写了一个解决方法:

http://andydunkel.net/delphi/coding/2013/11/23/firemonkey_xe_4_taborder_workaround.html

我正在使用FormHelper类,Form的键向下方法(对Tab键做出反应)和控件的帮助上下文属性。

首先我设置了帮助上下文,你也可以使用标签。但是我已经在使用tag属性了:

enter image description here

unit FormHelper;

interface

type
  TFormHelper = class helper for TForm
    procedure DoTabHandlingXE(comp : TForm; tabOrder : Integer);
  end;

implementation

//Workaround for Tab-Bug in Firemonkey
procedure TFormHelper.DoTabHandlingXE(comp: TForm; tabOrder : Integer);
var
  i, c :integer;
  current : TComponent;
  currentNext : integer;
  focus : TStyledControl;
begin
  c := Self.ComponentCount - 1;
  currentNext := 9999;
  focus := nil;

  for i := 0 to c do begin
      current := Self.Components[i];
      if (current is TStyledControl) then begin
          if ((current as TStyledControl).HelpContext < currentNext) and 
          ((current as TStyledControl).HelpContext > tabOrder) then begin
            currentNext := (current as TStyledControl).HelpContext;
          end;
      end;
  end;  

  for i := 0 to c do begin
      current := Self.Components[i];
      if (current is TStyledControl) then begin
        if (currentNext = (current as TStyledControl).HelpContext) then begin
          focus := (current as TStyledControl);
        end;
      end;
  end;

  if focus <> nil then begin
    focus.SetFocus;
end;
end;
end.

当然,代码没有做任何事情,因为该方法尚未调用。因此,下一步是以以下形式实现KeyDown事件:

procedure TfrmEinzField.KeyDown(var Key: Word; var KeyChar: Char;
  Shift: TShiftState);
var
  control : TStyledControl;
begin
  if Key = vkTab then
  begin
    //custom handling
    if (Self.GetFocused is TStyledControl) then begin
      control := (Self.GetFocused as TStyledControl);
      DoTabHandlingXE(Self, control.HelpContext);
    end;
  end else
    inherited; //do default handling
end;

在代码中,我们获得了当前关注的控件。然后我们使用当前的Form变量和控件HelpContext值调用我们之前编写的方法。使用该解决方法,tab键现在按预期工作,跳转到下一个控件。

更多详情请见博文。

答案 4 :(得分:0)

我遇到了同样的问题并找到了一个简单的解决方法:只需确保创建顺序是您的Tab键顺序。您可以通过编辑(文本)表单文件(.fmx)来完成此操作。 (在表单设计模式下按F12键) 例如: 如果您的表单只有3个编辑控件,则看起来像这样:

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 154
  ClientWidth = 215
  FormFactor.Width = 320
  FormFactor.Height = 480
  FormFactor.Devices = [dkDesktop, dkiPhone, dkiPad]
  DesignerMobile = False
  DesignerWidth = 0
  DesignerHeight = 0
  DesignerDeviceName = ''
  DesignerOrientation = 0
  DesignerOSVersion = ''
  object Edit1: TEdit
    Touch.InteractiveGestures = [igLongTap, igDoubleTap]
    TabOrder = 0
    Position.X = 40.000000000000000000
    Position.Y = 88.000000000000000000
    Width = 100.000000000000000000
    Height = 22.000000000000000000
    KillFocusByReturn = False
  end
  object Edit2: TEdit
    Touch.InteractiveGestures = [igLongTap, igDoubleTap]
    TabOrder = 1
    Position.X = 40.000000000000000000
    Position.Y = 56.000000000000000000
    Width = 100.000000000000000000
    Height = 22.000000000000000000
    KillFocusByReturn = False
  end
  object Edit3: TEdit
    Touch.InteractiveGestures = [igLongTap, igDoubleTap]
    TabOrder = 2
    Position.X = 40.000000000000000000
    Position.Y = 24.000000000000000000
    Width = 100.000000000000000000
    Height = 22.000000000000000000
    KillFocusByReturn = False
  end
end

标签顺序为Edit1:,Edit2:,Edit3:

如果您将其更改为:

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 154
  ClientWidth = 215
  FormFactor.Width = 320
  FormFactor.Height = 480
  FormFactor.Devices = [dkDesktop, dkiPhone, dkiPad]
  DesignerMobile = False
  DesignerWidth = 0
  DesignerHeight = 0
  DesignerDeviceName = ''
  DesignerOrientation = 0
  DesignerOSVersion = ''
  object Edit1: TEdit
    Touch.InteractiveGestures = [igLongTap, igDoubleTap]
    TabOrder = 0
    Position.X = 40.000000000000000000
    Position.Y = 88.000000000000000000
    Width = 100.000000000000000000
    Height = 22.000000000000000000
    KillFocusByReturn = False
  end
  object Edit3: TEdit
    Touch.InteractiveGestures = [igLongTap, igDoubleTap]
    TabOrder = 2
    Position.X = 40.000000000000000000
    Position.Y = 24.000000000000000000
    Width = 100.000000000000000000
    Height = 22.000000000000000000
    KillFocusByReturn = False
  end
  object Edit2: TEdit
    Touch.InteractiveGestures = [igLongTap, igDoubleTap]
    TabOrder = 1
    Position.X = 40.000000000000000000
    Position.Y = 56.000000000000000000
    Width = 100.000000000000000000
    Height = 22.000000000000000000
    KillFocusByReturn = False
  end
end

比Tab键顺序为Edit1:,Edit3:,Edit2:无论TabOrder属性的值是什么