描画順序 (Z オーダー)

描画順序 (Z オーダー) はコントロールの作成順序に基いています。

この順序を変更するには [フォームデザイナ] 或いは [構造] ペインで [コントロール | 前面へ移動] / [コントロール | 背面へ移動] を使います。コードで書くには BringtoFront() / SendToBack() メソッドを使います。

複雑なフォームの場合には一つ一つ手前にやったり背面にやったりするのはあまりにも非効率的です。この場合には、フォームファイルを直接編集して作成順序を変更しましょう。フォームファイルの編集方法については

を参考にしてください。ちなみに [フォームデザイナ] を右クリックした時の [作成順序] ダイアログではビジュアルコンポーネントの作成順序は変更できません。


描画順序を一気に設定する

面倒なのです…それでも面倒なのです。ここはコードで一気に描画順序を変更してみましょう。

作成順序は Button1→Button2→Button3→Button4→Button5 となっているため、その通りに描画されています。これを逆にしてみます。まずは以下のユニットを用意してください。

{*******************************************************}
{                                                       }
{              Delphi FireMonkey Platform               }
{                                                       }
{       Copyright(c) 2014 Hideaki Tominaga (DEKO)       }
{                                                       }
{*******************************************************}
unit FMX.ZOrder;

interface

uses
  FMX.Types;

{$IF (not Declared(FireMonkeyVersion)) or (CompilerVersion < 24.0)}
const
{$HPPEMIT '#define FireMonkeyVersion 16.0'}
  FireMonkeyVersion = 16.0;
{$EXTERNALSYM FireMonkeyVersion}
{$IFEND}

procedure ZOrderByTag(FmxObj: TFmxObject; Recursive: Boolean = True);

implementation

{ ZOrderByTag }
{$IF (FireMonkeyVersion < 17.0)}
function SortRoutine(Left, Right: TFmxObject): Integer;
begin
  if (Left <> niland (Right <> nil)  then
    result := Left.Tag - Right.Tag
  else
    result := 0;
end;
{$IFEND}

procedure ZOrderByTag(FmxObj: TFmxObject; Recursive: Boolean);
var
  i: Integer;
begin
  if (FmxObj = nilor (FmxObj.Name = ''then
    Exit;
  {$IF (FireMonkeyVersion < 17.0)}
  FmxObj.Sort(SortRoutine);
  if Recursive then
    for i:=0 to FmxObj.ChildrenCount-1 do
      ZOrderByTag(FmxObj.Children[i], Recursive);
  {$ELSE}
  FmxObj.Sort
  (
    function (Left, Right: TFmxObject): Integer
    begin
      if (Left <> niland (Right <> nilthen
        result := Left.Tag - Right.Tag
      else
        result := 0;
    end
  );
  if Recursive then
    for i:=0 to FmxObj.ChildrenCount-1 do
      ZOrderByTag(FmxObj.Children.Items[i], Recursive);
  {$IFEND}
end;

end.

よくよく見ると大した事はやっていません…XE2 対応のためにちょっと長くなっているだけです。このユニットで定義されている ZOrderByTag() を使うとコントロールの Tag プロパティの順が描画順序となります

uses
  ...,  FMX.ZOrder;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ZOrderByTag(Self);
end;

ボタンの Tag プロパティに描画順序を設定した上でフォームの OnCreate イベントハンドラに ZOrderByTag() を仕込むと Tag プロパティの順に描画されます…つまり Tag プロパティが小さい方が奥、大きい方が手前に描画されます。

See Also:


 BACK