8

TCustomPanel他の2つのコンポーネント(たとえば2つの編集)で構成されるカスタムコンポーネント(から継承)があります。コンポーネントを使用するときにタブの順序を正しく取得するにはどうすればよいですか?

タブオーダーデザイナでは、パネルであるためフォーカスを持てないコンポーネント自体にしかアクセスできません。実行時に何が起こるかというと、タブキーを使用して編集にアクセスできますが、コンポーネントの下にある2つのボタンがフォーカスされた後でのみです。

この状況でタブの順序を変更するにはどうすればよいですか?

4

1 に答える 1

13

コンポーネント内のネストされたコントロールのタブ順序は、コンポーネントが存在するフォームのタブ順序とは異なります。フォームのタブ順序リスト内のコンポーネントのタブ順序は、ネストされたコントロールにタブで移動したときに決まります。すべてのタブオーダーリストを組み合わせると、最終的なサイクルになります。

  • フォームのコントロール(TabOrder=0
  • フォームの別のコントロール(TabOrder=1
  • パネルコンポーネント(TabOrder=2
    • 編集1(TabOrder=0
    • 編集2(TabOrder=1
  • フォームの別のコントロール(TabOrder=3

パネルコンポーネントの設計時のタブ順序を設定できるようにするには:

  • デザイナのタブ順序エディタを使用して(コンポーネントの親を右クリック)、エディタの矢印を使用してタブ順序を変更するか、または
  • コンポーネントのプロパティを公開TabOrderし、オブジェクトインスペクターで設定します。

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

TabOrderプロパティはでパブリックとして宣言されているため、実行時にコンポーネントのタブ順序を設定することは常に可能TWinControlです。

...パネルなのでピントが取れません。

いいえ、パネルはフォーカスをうまく取得できますが、デフォルトではそうではありません。これは、デフォルトのTabStopプロパティで処理Falseされます。(1)パネルにはフォーカスのあるインジケーターがなく、(2)望ましくないため、コンポーネントTabStopに設定する必要はありません(私は想像します)。True


ネストされたコントロールのタブ順序の変更は、コンポーネントのコンストラクターで、または実行時に行うことが望ましいです。

設計時にコンポーネント内のネストされたコントロールのタブ順序を設定できるようにするには、さらに作業が必要です。私はあなたがそれを望んでいないと思いますが、私の前の答え(削除された)がゴミだったので(そして、ひどく投票しました)、私は補償として例を考え出しました。

まず、デザイナーのタブ順序エディターでこれらの編集のタブ順序を設定すると(パネルコンポーネントを右クリック)、タブ順序が変更されますが、長続きしないことに注意してください。これは、これらの変更がDFMにストリーミングされないためです。

コントロールの設計時の変更をストリーミング/保存できるようにするには、それらを公開する必要があります。

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;

もちろん、これはそれらのコントロールのすべてのプロパティを公開し、ユーザーは好きなように変更できるようになりました。これを防ぐには、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.

TEditこれにより、公開されたプロパティのプロパティがのみ表示されるように制限されますTabOrder

于 2012-04-17T15:54:05.510 に答える