開発者は、Tabキーが押された後のカーソルの位置に注意を払うことが重要なフォームを作成するように要求されることがよくあります。 これは、クロスプラットフォームアプリを開発する場合に特に重要になる可能性があります。クロスプラットフォームアプリでは、ユーザーインターフェースの動作に関するユーザーの期待に応えることで、アプリをプロフェッショナルに見せることができます。 これは、ユーザーエクスペリエンス、クライアントの要件、機能といった重要な事項など、さまざまな観点から重要視されます。 Delphiでは、「TabOrder」プロパティが実装されており、これらの要求に幅広く対応できます。
この記事では、DelphiのTabOrderプロパティに着目し、それがどのようにサポートされているか、どのように使用できるかを分析し、どのような制限があるかを紹介します。
Table of Contents
TabOderとその役割
Delphi 1のリリース以来、TabOrderプロパティはずっとDelphiの一部です。Delphiの以前のバージョンでは、TabOrderはVCL階層の一部でしたが、最近のバージョンでは、階層に小さな変更が加えられFMXの一部になっています。
Tabキーを押すと、フォーカスが1つのコントロールから次のコントロールに移動します。UIのデザイン特性により、すべてのコントロールがフォーカスを受け取ることができるわけではなく(例 TLabel)、すべてのコントロールがタブナビゲーションに関わるわけでもありません。フォーカスを受け取ることができるコントロールは、タブシーケンスに明示的に含まれている必要があります。
VCLでは、TabOrderはTWinControlクラスで定義されています。TabOrderプロパティを持つコンポーネントは、通常TWinControlクラスから派生しており、TWinControlクラスによって共通の扱いが可能になります。
以下に、TWinControlクラスのTabOrderプロパティの一般的な定義を示します。
[crayon-6768ab402080f129328884/]TTabOrderは、-1から32767までの値を設定できる列挙型として定義されます。
TabOrder値-1を持つコントロールは、Tabキーが押されたときのタブ移動からスキップされます。
クロスプラットフォームアプリでTabOrderはどのように異なるか?
FMXでは、TabOrderはTControlクラスの一部であり、上記のVCLのTWinControlクラスと同様に宣言されます。
コントロールがフォーカスを受け取るかどうかを決定するTabStopという名前のプロパティがもう1つあります。TabStop値がFalseのコントロールは、TabOrder値に関係なくフォーカスを受け取りません。この原則は、TabOrderの値が-1に等しい場合と似ています。
エンバカデロのドキュメントによると、TabOrderプロパティは、親のタブオーダーでのコントロールの位置として示されます。
これは、親コントロールが子となるコントロールの序列をそれぞれ持っているということを意味します。親フォームに追加されたすべてのコントロールは、親フォームが管理するタブオーダーで管理されます。(各コントロール内に追加された子コントロールを除く)。
TabOrderが0に設定されている親フォームのコントロールは、フォームが最初に表示されたときにフォーカスを持ちます。
デザイン時にコンポーネントを作成する場合、タブの順序は常にコントロールがフォームに追加された順序となります。フォームに追加された最初のコントロールのTabOrder値は0、2番目のコントロールの値は1、3番目のコントロールの値は2というようになります。上記のTabOrderプロパティの宣言で見たように、TabOrderは書き込み可能なプロパティです。したがって、必要に応じていつでもTabOrder値を変更できます。TabOrderは整数の列挙であるため、その値は-1から32767の範囲内にある必要があります。
クロスプラットフォームアプリでコントロールのTabOrderを設定する方法
各コントロールには、その親内に一意のTabOrder値があります。あるコントロールのTabOrderプロパティ値を別のコントロールと同じ値に変更すると、同じ親フォーム上の他のすべてのコントロールのTabOrder値もそれに応じて変更されます。 例えば、コントロールがタブ順で6番目であるとします。 コントロールのTabOrderプロパティ値を3に変更すると(コントロールのタブ順を4番目にする)、元々タブ順が4番目だったコントロールが5番目になり、5番目であったコントロールが6番目になります。
親コントロールに含まれるコントロールの数よりも大きいTabOrder値を割り当てると、基本的にコントロールはタブオーダーの最後に移動します。 コントロールは、割り当てられたTabOrderの値を受け付けませんが、代わりに、コントロールがタブオーダーの最後の番号を取得します。
FMXでのTabOrderの使用法を示すために、Delphiでアプリケーションを作成しました。 見栄えはよくありませんが、以下で確認できます。
上のスクリーンショットで、複数のコントロールを備えたフォームが確認できます。
一般的に、このようなフォームを作成するときは、ユーザーエクスペリエンスの観点から正しいタブ順を確保する必要があります。
タブ順の要件に基づいたコントロールの作成
1つの方法は、設計時にコントロールを作成しながら正しく処理することです。このアプローチでは、要件に応じてタブの順序が正しくなるようにコントロールを作成する必要があります。ただし、要件変更に伴う変更の可能性によりユーザーインターフェースが大幅に変更されるため、このアプローチに従うことが常に可能であるとは限りません。
以下のスクリーンショットでは、要件に従ってコントロールのすべてのTabOrderプロパティを設定する方法を確認できます。
ここで、最初のコンポーネントのTabOrderは0に設定されています。
ボタンA、B、C、およびDが配置されているパネルでは、TabOrderが1に設定されています。これは下のスクリーンショットに示されています。
すでに説明したように、各親コントロールには独自のタブ順のリストがあります。これは、次のスクリーンショットに示されています。
ボタンAは、親フォームではなくパネルの子コンポーネントであるため、TabOrderは0です。 他のボタンのタブ順については以下に示します。
従って、フォーム上のすべてのコントロールに対してオブジェクトインスペクタから手動でTabOrderプロパティを設定することは、アプリケーションでフォーカスの正しい流れを確保する方法の1つです。 しかし、これは、フォームにさらに多くのコントロールを追加する場合、非常に面倒になります。
TabOrderの設定に「タブ順序」ダイアログボックスを使用する
エンバカデロは、開発者が経験するDelphiフォームでコントロールのタブ順を設定する際の、すべての複雑さを十分に認識しているようです。
この作業を簡素化するために、IDEに、親コントロールのすべてのコントロールのTabOrder値を一度に設定するオプションを提供しています。 親コンポーネントを右クリックして、[タブ順序]メニューを選択します。
選択後、その親コンポーネントのすべての子コントロールがタブ順に一覧表示されるダイアログボックスが表示されます。
必要に応じ、コントロールを上下に移動し、タブ順序を設定することができます。
「タブの順序の設定」ダイアログ機能は、複数のタブ、パネル、および多数のコンポーネントを含むフォームの場合に非常に役立ちます。 これは通常、タブの順序に関して遭遇するほぼすべての要件を達成するのに役立ちます。
TabOrderの設定にサードパーティのCnWizardsIDEアドインコンポーネントを使用する
開発者は、IDEが提供する機能によってソリューションが制限されることを想定していません。 言い換えれば、これらの機能を自由に探り、作成、拡張して、作業を楽にすることができます。
CnPackコミュニティはこの原則に従い、Delphi開発者コミュニティに役立つオープンソースのコンポーネントを作成しました。
非常に役立つコンポーネントの1つは、CnWizardsです。 現在提供されている機能全体については今回説明しません。 私たちのケースに関連するものを見てみましょう。それはTabOrderウィザードです。
TabOrderウィザードはCnWizardsコンポーネントであり、コンポーネントのTabOrderをすばやく設定、変更(自動および手動、水平および垂直)、表示、およびその他の多くのタスクを実行するために必要な機能を提供します。
この記事は、エンバカデロ・テクノロジーパートナーの Softacomによって作成されました。 Softacomは、Delphiにフォーカスしたあらゆる種類のソフトウェア開発を専門としています。 SoftacomのWebサイトでサービスの詳細をご覧ください。