1

I have 3 custom tRectangle on a form. When creating the custom tRectangle, I set CanFocus = True;, so the tRectangle can be focused. On FormCreate event, I set the TabOrder to 0 to the first tRectangle, to 1 to the second tRectangle and to 2 to the third tRectangle.

When running the application, the first tRectangle, since it's TabOrder is 0, should get the focus, but it does not.

Also, when tabbing, the second control gets focus, then the third control and at this point the focus gets stuck. Now, if tabbing with the Shift key pressed, the second control gets focus, until it reaches the first control, and again the focus gets stuck.

I appreciate if anyone can tell me why the control with TabOrder 0 is not focused at runtime and why tabbing is not acting in a circular way.

Follows code:

unit frmMyRect; interface uses FMX.Controls, FMX.Controls.Presentation, FMX.Forms, FMX.Layouts, FMX.Objects, FMXFMX.StdCtrls, FMX.Types,System.Classes, System.UITypes; type tfrmMyRect = class (tForm) procedure FormCreate (Sender: tObject); end; tMyRect = class (tRectangle) fMyRectLabel : tLabel; constructor Create (aOwner : tComponent); procedure MyRectClick (Sender: tObject); procedure MyRectEnter (Sender: tObject); procedure MyRectExit (Sender: tObject); function GetText : string; procedure SetText (const aText: string); published property Text : string read GetText write SetText; end; var formMyRect: tfrmMyRect; implementation {$R *.fmx} var MyRect1 : tMyRect; MyRect2 : tMyRect; MyRect3 : tMyRect; procedure tformMyRect.FormCreate (Sender: tObject); begin MyRect1 := tMyRect.Create (Self); MyRect1.Parent := frmMyRect; MyRect1.TabOrder := 0; MyRect1.Text := 'MyRect&1'; MyRect2 := tMyRect.Create (Self); MyRect2.Parent := frmMyRect; MyRect2.TabOrder := 1; MyRect2.Text := 'MyRect&2'; MyRect3 := tMyRect.Create (Self); MyRect3.Parent := frmMyRect; MyRect3.TabOrder := 2; MyRect3.Text := 'MyRect&3'; end; { FormCreate } constructor tMyRect.Create (aOwner: tComponent); begin inherited; CanFocus := True; Height := 23; OnClick := MyRectClick; OnEnter := MyRectEnter; OnExit := MyRectExit; TabStop := True; Width := 80; fMyRectLabel := tLabel.Create (Self); with fMyRectLabel do begin Align := tAlignLayout.Center; FocusControl := Self; HitTest := False; Parent := Self; StyledSettings := []; TabStop := False; with TextSettings do begin FontColor := TAlphaColorRec.Blue; WordWrap := False; Font.Style := [TFontStyle.fsBold]; end; end; end; { Create } procedure ctMyRect.MyRectClick (Sender: tObject); begin Fill.Color := TAlphaColorRec.Aqua; end; procedure ctMyRect.MyRectEnter (Sender: TObject); begin Fill.Color := TAlphaColorRec.Aqua; end; procedure ctMyRect.MyRectExit (Sender: TObject); begin Fill.Color := TAlphaColorRec.Beige; end; end. 
4
  • Assuming you are using the tMyRect from your previous question, how are you indicating the focused rectangle? If you are not using tMyRect please show code with which the problem can be reproduced. Commented Sep 8, 2019 at 20:44
  • @Tom Brunberg Your Right. I inserted code for handling the OnCanFocusevent, and the tRectangle with the TabOrder 0 is focused, but the tabStop issue remains. Any tip? Commented Sep 8, 2019 at 22:48
  • You really ought to provide a minimal reproducible example, so this is just pure speculation: maybe you haven't set TabStop := True for the first TMyRect. When I set both TabOrder and TabStop for three of your TMyRect, tabbing works as expected. If I leave TabStop := False for the first TMyRect then tabbing never goes to that rectangle, but goes 1-2-1-2-1..., so, no locking as you describe. Commented Sep 9, 2019 at 5:43
  • @Tom Brunberg Sorry. My mistake. Follows an example: Commented Sep 9, 2019 at 14:09

1 Answer 1

2

1. Control with TabOrder = 0 is not focused when form first appears

I can confirm this with your code and also with e.g. TEdit controls. Consider two edit controls on a form. When added to the form in the designer, the first one added got TabOrder = 0. When the form is first shown, neither has focus. After a Tab entry, the first created receives the focus.

From help for FMX.Controls.TControl.TabOrder:

TabOrder is the order in which child controls are visited when the user presses the TAB key. The control with the TabOrder value of 0 is the control that has the focus when the form first appears.

The second sentence is not correct. But the control with TabOrder = 0 will be the first to receive focus when user hits Tab key.

To assure that a specific control has focus already when the containing form appears, set:

Focused := MyRect1; 

or, maybe better:

MyRect1.SetFocus; 

in the forms OnCreate() event.


2. Tabbing is not acting in a circular way

After trying your code, I still cannot reproduce the problem you claim. Maybe you are just misjudging what appears to you.

Because of this line at the beginning of constructor tMyRect.Create():

Align := tAlignLayout.Center; 

all rects are on top of each other in the center of the form, IOW you can only see the top one. (Focused controls are not automagically brought to the front) Remove that line and place the rects appart (position.X and position.Y) so you can see which one is currently focused.

The line FocusControl := Self; seems misplaced (in XE7 at least), so I outcommented it.

TAB through the tMyRect controls works exactly as expected, in the order:

MyRect1 - MyRect2 - MyRect3 - Myrect1 ...

and Shift-TAB in the opposite order.

Sign up to request clarification or add additional context in comments.

4 Comments

Sorry for that Align := tAlignLayout.Center;. This is because in my application, I have three tLayouts already positioned on the form. On Create event, I set rects parents to the tLayouts, so they are correctly positioned on the form at runtime. In turn, the tLayouts are on a tRectangle (sorry, I am a bit neurotic with presentation issues). I made sure also, that only MyRect controls, can receive focus and respond for Tab key. The example has only MyRect's for the sake of simplicity.
It seems that the issue lies on those tRectangle and tLayouts. Somehow they interfire with the Tab functionality.
Yes, they do. Each parent arranges its own children in tab order. Each TLayout has as default a taborder according to the order they were placed on the form. If each TLayOut has only one control (TMyRect) they will all have by default TabOrder = 0, because they all have different parents. Now that the TMyRects have different parents there's no need to set their order when you create them. Set only the order of the TLayouts. I will recheck this tomorrow.
That's correct! I should have noticed that! I was so sure that I have to set TabOrder to MyRect controls, that I totally forgot that rule. The thing is that we only see our error when someone points it out for us. Thanks! I did the necessary corrections and Tab key works fine.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.