2014-02-14 46 views
1

我正在爲Windows平臺的Delphi XE5 Update 2寫一個Firemonkey HD程序。 我有一個tabitem tabitem在窗體和tabitem中的一些編輯框。當我輸入Edit1並點擊選項卡時,Edit1失去焦點,但Edit2沒有獲得焦點,所以我設置了Taborder(0,1,2,..)。德爾福firemonkey在tabcontrol中的tabstop問題

我試圖把編輯框放在主窗體和麪板上,並且它們在那裏正常工作,當我在edit1中並且按下tab鍵時,它會進入edit2等等,但是在tabcontrol中的tabitem上它不會。

有沒有人知道這個工作或可能是我錯過了一個設置?

感謝所有幫助

回答

0

我有同樣的問題在我的應用程序,所以我寫了一個解決辦法:

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

我使用一個表單助手類,關鍵下來形式的方法(反應Tab鍵)和控件的幫助上下文屬性。

首先,我設置幫助上下文,您也可以使用標記。不過,我已經使用的標籤屬性別的東西:

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鍵現在按預期工作,跳到下一個控件。

更多詳情請見博客文章。

1

這是一個已知的bug: http://qc.embarcadero.com/wc/qcmain.aspx?d=117380

看起來它可能是固定的XE6。

您可以使用Control.SetFocus手動設置焦點,但是您必須爲每個控件自行設置焦點。您可以設置OnKeyUp事件並查看他們是否按下了選項卡(VK_TAB或9),以及他們是否將焦點設置到了下一個控件。

+0

感謝您的qc鏈接。我開始手動操作,但有50個控件,其中一些隱藏了一些時間,它非常繁瑣。我必須看看是否有一種方法可以通過編程實現,Taborder已經存在。我需要通過所有的控制,看看下一個是誰。或者可以將它們存儲在一個數組中。再次感謝您的幫助 – ettore

+0

請注意[QualityCentral現在已關閉](https://community.embarcadero.com/blogs/entry/quality-keeps-moving-forward),因此您無法訪問'qc.embarcadero .com'鏈接了。如果您需要訪問舊的QC數據,請查看[QCScraper](http://www.uweraabe.de/Blog/2017/06/09/how-to-save-qualitycentral/)。 –

0

我有同樣的問題,並發現一個簡單的解決方法:只要確保創建的順序是您的標籤順序。您可以通過編輯(文本)表單文件(.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屬性的值是

+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)

+0

我在我的主表單中有一個tabcontrol,我插入了框架,這個修復解決了tabb字段的問題 –

1

我以非常簡單的方式解決了這個問題。 我改變了表格的高度爲2000,並在我的滾動框中插入了字段。 然後我將表格的高度返回到原來的位置。 據我所知,當組件位於滾動框的可見區域外時,firemonkey會丟失。但是如果窗體的高度更大,那麼滾動框會認爲一切都可見並且工作正常。

+0

你能提供包含你的解決方案的代碼片段嗎? – jkalden