2014-02-14 1 views
1

Я пишу программу Firemonkey HD в Delphi XE5 Update 2 для платформы Windows. У меня есть tabcontrol с tabitem в форме и некоторые поля редактирования в tabitem. У меня установлен таборд (0,1,2, ..), когда я вхожу в Edit1 и нажимаю вкладку, Edit1 теряет фокус, но Edit2 не получает фокуса.Проблемы с таблетками Delphi firemonkey в tabcontrol

Я попытался помещать поля редактирования в основной форме и на панели, и там они работают правильно. Когда я нахожусь в edit1 и нажимаю вкладку, он переходит к edit2 и т. Д., Но на tabitem в tabcontrol он не ,

Кто-нибудь знает о работе вокруг этого или, может быть, настройке, которую я пропустил?

Спасибо за любую помощь

ответ

0

Я была такая же проблема в моем приложении, поэтому я написал обходной путь:

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

Я использую класс FormHelper, ключ вниз метод формы (реагирует на 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 элементов управления. С этим обходным ключом ключ вкладки теперь работает как ожидалось, переходя к следующему элементу управления.

Подробнее в блоге.

1

Это известная ошибка: http://qc.embarcadero.com/wc/qcmain.aspx?d=117380

Похоже, это может быть исправлено для XE6.

Вы можете вручную установить фокус с помощью Control.SetFocus, но тогда вы должны настроить это для каждого элемента управления. Вы можете настроить событие OnKeyUp и посмотреть, нажали ли они вкладку (VK_TAB или 9), и если они сделали фокус на следующем контроле.

+0

спасибо за ссылку qc. Я начал делать это вручную, но с 50 элементами управления, и некоторые из них скрыты некоторое время, это становится довольно утомительным. я должен посмотреть, есть ли способ, который я мог бы сделать это программно, табордер уже существует. Мне нужно будет пройти через все элементы управления и посмотреть, кто следующий. или, возможно, сохранить их в массиве. спасибо за вашу помощь снова – 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 

чем табуляции не Edit1 :, Edit3 :, Edit2: независимо от того, какое значение свойства TabOrder является

+0

Пожалуйста, объясните, что вы изменили в коде, скопировать-вставить недостаточно. –

2

Вот фактическое исправление проблемы, которое я также описал в http://vldgeorgiev.wordpress.com/2014/04/01/delphi-tab-key-and-taborder-not-working

Он лежит в источнике TTabItem в блоке FMX.TabControl.pas.
Существует перекрытый метод называется 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 метод одной из форм обрабатывает Таб ключ он вызывает AdvanceTabFocus метод, который проверяет FTabList для любых дочерних компонентов. Поскольку у оригинального метода TTabItem DoAddObject отсутствовала строка, он никогда не добавлял дочерние элементы управления в этот список, поэтому метод AdvanceTabFocus не может найти следующий элемент управления. Вместо этого он устанавливает фокус на первый элемент управления в форме.

Чтобы использовать это исправление, скопируйте измененный блок FMX.TabControl.pas рядом с вашими проектными файлами или скомпилируйте DCU и поместите их в подпапки Lib ... из папки установки Delphi. Если у вас нет источников, вам не повезло.

Btw, установка номеров TabOrder не всегда достаточно. Вы должны щелкнуть правой кнопкой мыши и использовать «Порядок вкладок ...» или даже вручную изменить порядок элементов управления в тексте форм (с помощью Alt-F12)

+0

У меня есть tabcontrol в моей основной форме, где я вставляю Frames, это исправление решает проблему сложения полей –

1

Я решил это очень простым способом. Я изменил высоту формы на 2000 и вставил поля в свою прокрутку. Затем я вернул высоту формы к оригиналу. Из того, что я понимаю, firemonkey теряется, когда компонент находится за пределами видимой области прокрутки. Но если форма имеет большую высоту, scrollbox считает, что все видно и работает.

+0

Можете ли вы предоставить фрагмент кода, который включает в себя ваше решение? – jkalden

 Смежные вопросы

  • Нет связанных вопросов^_^