我正在为Windows平台的Delphi XE5 Update 2编写Firemonkey HD程序。 我有一个tabcontrol,表格上有一个tabitem,tabitem中有一些编辑框。我有相应的taborder设置(0,1,2,..),当我进入Edit1并按Tab键时,Edit1失去焦点但Edit2没有得到焦点。
我尝试将编辑框放在主窗体和面板中,然后它们正常工作,当我在edit1并点击选项卡时,它会转到edit2,依此类推,但在tabcontrol中的tabitem却没有。
有没有人知道这方面的工作或者我错过的设置?
感谢您的帮助
答案 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属性了:
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属性的值是什么