2

TTabsheets のタブを非表示にして TPageControl を使用して、含まれるフレームが積み重ねられているように見せ、プロセスのさまざまなステップで別のフレームを表示することで、ある種のウィザードを構築しています。

問題は、「PageControl1.ActivePageIndex := x;」を呼び出した後です。次のフレームを表示するには、新しいフレームに入ったら、どのようにしてここに到達したか、つまり以前にどのフレームが表示されたかを知る必要があります。

他の誰かがページ コントロールのフレームを使用してウィザードを作成した場合、前/次のフレームをどのように追跡しますか?

ありがとうございました。

4

6 に答える 6

5

TPageControl には、変更前に呼び出される OnChanging というイベントがあり、パラメーターを false に設定することで変更をキャンセルできます。

このイベントを使用して、変更前にアクティブだったページを記録することもできます。

ただし、GUI コンポーネントにあまり強く結合されていないものを作成することをお勧めします。フレームを保持し、あるフレームから別のフレームへの変更が許可されているかどうかを確認するクラスを作成してみてください。これにより、ウィザードを視覚化するために使用する GUI コントロールの種類を簡単に切り替えることができます。また、検証ルールが適用されているかどうかなど、ウィザードが必要な段階的な進行を提供するかどうかを確認するためのテストがはるかに簡単になることは間違いありません.

于 2009-08-22T20:46:22.613 に答える
1

delphi.about.com には、ウィザードのようなユーザー インターフェイスを作成する方法に関する記事があります。TPageControl.SelectNextPage メソッドを使用して、一連のページを前後に移動できます。

于 2009-08-22T21:05:00.173 に答える
1

Nat の回答に反してtpagecontrol.onchanging、適切な方法を使用してページを変更すると、イベントは正常に機能します。

VCL フォーム アプリケーションを作成し、 にドロップしてTPageControl、Align プロパティを alTop に設定し、下にいくつかのスペースを残します。PageControl を右クリックし、いくつかのページを追加して、TabVisible:=falseそれぞれに設定します。次に、下にいくつかのボタンを追加します。PageControl のonchangingイベントとボタンのonclickイベントを、以下のそれぞれのコードに添付します。

procedure TForm1.Button1Click(Sender: TObject);
begin
  if PageControl1.ActivePageIndex < PageControl1.PageCount - 1 then
    PageControl1.SelectNextPage(true, false);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if PageControl1.ActivePageIndex > 0 then
    PageControl1.SelectNextPage(false, false);
end;

procedure TForm1.PageControl1Changing(Sender: TObject;
  var AllowChange: Boolean);
begin
  showmessage(format('now leaving page number %d', [PageControl1.ActivePageIndex]));
end;

これは期待どおりに機能します (BDS2006、RAD2009)。

于 2009-08-25T02:26:41.493 に答える
0

以前のページ インデックスを手動で追跡する必要があります。たとえば、[次へ] ボタンと [前へ] ボタンの OnClick イベント ハンドラーでは、次のようにすることができます。

procedure TWizardForm.NextClick(ASender: TObject);
begin
  SwitchPage(True);
end;

procedure TWizardForm.PreviousClick(ASender: TObject);
begin
  SwitchPage(False);
end;

SwitchPage() は次のようになります。

procedure TWizardForm.SwitchPage(AForward: boolean);
var
  LGotoPage: integer;
begin
  LGotoPage := PageControl.ActivePageIndex;

  if AForward and (PageControl.ActivePageIndex < PageControl.PageCount) then
    inc(LGotoPage)
  else if PageControl.PageIndex > 0 then
    dec(LGotoPage);

  if (LGotoPage <> PageControl.ActivePageIndex) 
    and AllowSwitchFrom(ActivePageIndex) then
  begin
    FPreviousPage := PageControl.ActivePageIndex;
    PageControl.ActivePageIndex :=  LGotoPage;
  end;

end;

またはその趣旨の何か。:)

編集: Argalatyrは正しく、ウィザードを順番に移動したい場合は間違っています。ここではそうです。

OnChanging ハンドラーは実際に起動し、元のページは (まだ) アクティブなページです。

私の例のようにページ インデックスを直接設定した場合、OnChanging イベントは発生しないため、古いページ インデックスを追跡する必要があります。これは、オプションのページ (シーケンシャルではない) を使用してウィザードをコーディングすることから来ています。

投稿する前にもう少しよく確認するべきでした。間違った答えをお詫びします。

N@

于 2009-08-25T01:43:29.587 に答える
0

私は、あなたがやろうとしていることをほぼ実行するウィザード フレームワークを作成しました。そのほとんどは私のブログに記載されています。私が使用した解決策は、(インターフェイスを使用して) 次/前のページの要求をフレーム自体にプッシュし、フレームに次のフレームを決定させることでした。

2 つのアイデアをマージしたい (tPageControl をそのまま維持する) 場合は、要求を tPageControl.ActivePage にルーティングするだけで、NavigateToPage の実​​装のために、特定のページを見つけようとするのではなく、名前を付けたページを検索できます。クラス。

私のウィザード フレームワークの設計は、途中で下された決定に基づいて複数のパスを含むいくつかの複雑なウィザードを処理することでした。前のフレームをリストに保存し、各フレームの「状態」はグローバルにアクセス可能なクラスに保存され、ウィザードが終了/キャンセルされるとクリアされました。

于 2009-08-24T16:14:11.953 に答える
0

また、JEDI VCL ライブラリの一部である Wizard コンポーネントも参照してください。

于 2009-08-24T07:58:03.783 に答える