2

Form1 から、アプリ内の Frame1 に配置されたボタン (SQLBtn など) にアタッチされたアクションを実行する必要があります。
フレームを Form1 の使用に含めましたが、どうにも対処できないようです。
Frame1.SQLbtn TFrame1.SQLbtn TFrameSQLBtn などを試しましたが、到達できません。
「SQLbtn.click」に似たものにアクセスして、その背後でイベントを実行したいと思います。

それに対処する方法はありますか?

4

4 に答える 4

6

あなたの質問を正しく理解しているかどうかわかりません。ボタン (およびボタンの TAction またはクリック イベント ハンドラのいずれか) を持つフレームがあり、このフレームがフォーム上にあるように聞こえます。次に、そのボタンのクリックをプログラムでシミュレートします。

明らかに、フレーム ユニットをフォームの uses 句に追加する必要があります。フレームタイプのフォームフィールドにつながるフォーム上のフレームのインスタンスも必要です。

TForm1...
  ...
  Frame1: TFrame1;
end;

Frame1.SQLbtn.Click次に、フォームの任意のメソッド内からそのコードを実行できます。より良い方法は、フォームから使用できるフレームにパブリック メソッドを提供することです。次に、ボタンに直接アクセスする必要はありません (ボタンはフレームの実装の詳細、いわばフレーム プライベートです)。

明確化後に編集

次のシナリオがあることを理解しています。

TFrameForm1...
  ...
  Frame1: TFrame1;
end;

TForm1...
  ...
  procedure something;
end;

procedure TForm1.something;
begin
  // how to call a method on Frame1 which is on FrameForm1
end;

フレーム ボタンの OnClick イベント ハンドラから別のユニットにコードを移動するのが最善の選択です。これは、データモジュール、またはスタンドアロンのプロシージャを持つ別のユニットにすることができます。次に、Form1 と Frame1 ボタン イベント ハンドラーの両方からそのコードを呼び出すことができます。これはVegarがコメントしたものです。

それが不可能な場合、たとえば、処理で Frame1 の他のコントロールへのアクセスが必要な場合は、コードを Frame1 の新しいプロシージャに移動します (私の最初の提案)。

TFrame1...
  ...
public
  procedure framestuff;
end;

procedure TFrame1.framestuff;
begin
  ...
end;

procedure TFrame1.SQLbtnClick(Sender...);
begin
  framestuff;
end;

ここで、Form1 からそのメソッドを呼び出す必要があります。そのためには、FrameForm1 への参照が必要です。TFrameForm1 を作成するときに手動で (!) 初期化する必要があります。この例では、参照はフィールド FFrameForm です。

TForm1...
  ...
  FFrameForm: TFrameForm1;
  procedure something;      
end;

procedure TForm1.something;
begin
  FrameForm.framestuff;
end;

または、デフォルトで、Delphi はすべてのフォームのグローバル変数をフォーム ユニットに追加します(フォームの自動作成、プロジェクト オプション / フォームのチェック)。次に、これを行います。

procedure TForm1.something;
begin
  FrameForm1.framestuff; // if FrameForm1 is the name Delphi used for the global variable
end;

もちろん、他にもたくさんのバリエーションがあります...

于 2009-01-27T23:32:32.343 に答える
1
procedure TDiferentForm.DoSomething();
begin
  Form1.YourFrame.ButtonClick(nil);
end;
于 2009-01-28T11:01:41.250 に答える
0

もう 1 つの解決策は、インターフェースを使用して循環参照の問題を回避し、コードを少し単純化することです。システムのどこからでも呼び出したいfooという名前のプロシージャがあるとします。このプロシージャの実装は、メイン フォームではなく、メイン フォームが認識しているフォームであるtFooFormにあります。

最初に新しいユニットを作成し、それをFoo_Intf.pasと呼びます

その内容は次のとおりです。

unit Foo_Intf;

interface

type
  IFoo = interface
    ['{4AC12AB9-557B-4E61-AB2D-8B10E591E33A}'] 
    // CTRL-SHIFT-G to create a new guid
    procedure Foo;
  end;

implementation

end.

次に、メソッドを tFooForm クラスに追加し、インターフェイスも含めます。インターフェイスの uses 句で foo_intf.pas ユニットを使用することを忘れないでください。foo クラスを実装して、そのプロシージャーに実行させたいことを実行します。

tFooForm = class(tForm,IFoo)
  :
  procedure Foo;
  :
end;

また、前の手順とまったく同じように IFoo インターフェイスをメイン フォームに追加しますが、実装を次のように変更します。

procedure tMainForm.Foo;
begin
  if not Assigned(FooForm) then
    FooForm := tFooForm.Create(Application);  // for simplicity sake
  FooForm.Foo;
end;

ここで、foo 関数を呼び出したい任意の場所で、uses 句に Foo_Intf ユニットのみを含め、次のスニピットを使用します。

var
  FooIntf : IFoo;
begin
  if Not Supports(Application.MainForm, IFoo, FooIntf) then
    Raise Exception.create('Application.mainform does not implement IFoo');   
  FooIntf.Foo;
end;
于 2009-01-29T17:01:57.460 に答える