Custom order and tab order

I have a custom component (inheriting from TCustomPanel ) that consists of two other components (say, two changes). How to get the right to a tab when using a component?

In the tab order designer, I can only access the component itself, which cannot have focus, because it is a panel. What happens at runtime is that I can access the editing using the tab key, but only after the two buttons under the component are focused.

How to reorder tabs in this situation?

+7
source share
1 answer

The tab order of these nested controls in your component is different from the tab order of the form on which your component is located. The order of component tabs in the list of orders for the form tab is preserved when inserted into nested controls. After combining all the lists of tab orders, they lead to the final cycle:

  • Form Control ( TabOrder=0 )
  • Other form control ( TabOrder=1 )
  • Panel Component ( TabOrder=2 )
    • Change 1 ( TabOrder=0 )
    • Edit 2 ( TabOrder=1 )
  • Other form control ( TabOrder=3 )

To set the order of tabs for the development time of a panel component:

  • Use the tab order editor in the designer (right-click on the parent element of the component) and change the order of the tabs with arrows in the editor or
  • Publish the TabOrder for your component and set it in the object inspector:

     type TMyPanel = class(TCustomPanel) published property TabOrder; end; 

At run time, you can always set the tab order for the component, since the TabOrder declared public in TWinControl .

... which cannot have focus, because it is a panel.

No, the panel can easily adjust the focus, but it will not be the default. This is done using the TabStop property, which defaults to False . You do not want TabStop set True for your component, because (1) the panel does not have an indicator in which it has focus, and (2) this is undesirable (I suppose).


Reordering the tabs of nested controls is preferably done in the constructor of your component or at runtime.

In order to be able to set the tab order of the nested controls inside your component during development, one more work is required. I don't think you want this, but since my previous answer (deleted) was garbage (and voted, weird), I developed an example as compensation.

First, note that setting the tab order of these changes using the tab order editor in the designer (right-click on a panel component) will change the tab order, but this will not continue. This is because these changes are not propagated to DFM.

In order to be able to transfer / save changes in the development time of controls, you need to publish them:

 type TMyPanel = class(TCustomPanel) private FEdit1: TEdit; FEdit2: TEdit; public constructor Create(AOwner: TComponent); override; published property Edit1: TEdit read FEdit1; property Edit2: TEdit read FEdit2; end; constructor TMyPanel.Create(AOwner: TComponent); begin inherited Create(AOwner); FEdit1 := TEdit.Create(Self); FEdit1.SetBounds(10, 10, 100, 21); FEdit1.Name := 'Edit1'; FEdit1.Parent := Self; FEdit1.SetSubComponent(True); FEdit2 := TEdit.Create(Self); FEdit2.SetBounds(10, 41, 100, 21); FEdit2.Name := 'Edit2'; FEdit2.Parent := Self; FEdit2.SetSubComponent(True); end; 

Of course, this publishes all the properties of these controls, and now users can change whatever they want. To prevent this, consider limiting the published properties of TEdit :

 unit MyPanelEdit; interface uses DesignEditors, Unit2, DesignIntf, SysUtils, Classes, TypInfo, StdCtrls; type TEditProperty = class(TComponentProperty) private function FilterFunc(const ATestEditor: IProperty): Boolean; public function GetAttributes: TPropertyAttributes; override; procedure GetProperties(Proc: TGetPropProc); override; end; procedure Register; implementation procedure Register; begin RegisterPropertyEditor(TypeInfo(TEdit), TMyPanel, '', TEditProperty); end; { TEditProperty } function TEditProperty.FilterFunc(const ATestEditor: IProperty): Boolean; begin Result := ATestEditor.GetName = 'TabOrder'; end; function TEditProperty.GetAttributes: TPropertyAttributes; begin Result := [paSubProperties]; end; procedure TEditProperty.GetProperties(Proc: TGetPropProc); var LComponents: IDesignerSelections; LDesigner: IDesigner; begin LComponents := GetSelections; if LComponents <> nil then begin if not Supports( FindRootDesigner(LComponents[0]), IDesigner, LDesigner) then LDesigner := Designer; GetComponentProperties(LComponents, [tkInteger], LDesigner, Proc, FilterFunc); end; end; end. 

This limits the properties of published TEdit properties to display only TabOrder .

+13
source

All Articles