动态地将表单放在页面控件上

时间:2014-02-24 15:41:18

标签: delphi

作为我之前帖子forms an a pagecontrol at runtime 的扩展 我需要一个解决方案如何将buttonclick事件传递回父页面控件。 我是否指定了一个单击功能作为属性,并为我放置的所有按钮的所有表单分配一个新的单击功能:-( ....很多工作,任何更好的解决方案

MyMainForm = CLass( )
....
aPagecontrol  : TPageControl;
aTabForm_1  : TTabForm_1 ;  //  in the real case I use an dynamic array 
aTabForm_2  : TTabForm_2 ;
aTabForm_3  : TTabForm_3 ;

....
UserData  : TUserdata ;   //  lot of user data ....


function MyMainForm.CreateTabAndForm:  TTabForm_1;
 var
 tabSheet : TTabSheet;
 begin
 //Create a new tab sheet
 tabSheet := TTabSheet.Create(PageControl1) ;
 tabSheet.PageControl := PageControl1;

 //create a form
 Result :=  TTabForm_1.Create(tabSheet) ;
 Result.Parent := tabSheet;
 Result.Align := alClient;
 Result.BorderStyle := bsNone;
 Result.Visible := true;
 tabSheet.Caption := Result.Caption;

  //activate the sheet
PageControl1.ActiveSheet := tabSheet;
end;





//  program code , now failing :  

 aTabForm_1 :=  CreateTabAndForm;
 aTabForm_1.onclick := MyButtonOnclick; //  here AV happens !!

....
end; 

表格的定义

//  
TTabForm_1 = class(TForm)
...


property clickButton1 : TClickfunction .......
end; 
  • 解决方案#1 - >使用属性

  • 将所有数据传递给TTabForm_1
  • 解决方案#2 - >将Button Click事件传递给Mainform

目标:可读代码 - 良好的设计

1 个答案:

答案 0 :(得分:3)

公开表单或控件中引发的事件的一种方法是这样的:

unit Unit2;

interface    
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;    
type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    FButton1Clicked : TNotifyEvent; //Create a private TNotifyEvent field
  public
    // ...and expose it as a property
    property OnButton1Click : TNotifyEvent read FButton1Clicked
                                           write FButton1Clicked;
  end;

implementation    
{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  // Execute the method if it has been assigned when Button1 is clicked.
  if Assigned(FButton1Clicked) then FButton1Clicked(Sender);
end;

end.

您将使用的内容如下:

unit Unit1; 

interface    
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Unit2;    
type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FForm2 : TForm2;
    procedure Form2ButtonClick(sender : TObject);//Create a TNotifyEvent handler
  end;    
var
  Form1: TForm1;

implementation    
{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FForm2 := TForm2.Create(self);
  //Assign a method to your custom event property
  FForm2.OnButton1Click := Form2ButtonClick; 
  FForm2.Show;
end;

procedure TForm1.Form2ButtonClick(sender: TObject);
begin
  // Do Something...
end;

end.

当然,您不必使用TNotifyEvent,您可以使用您喜欢的参数创建任何自定义事件。例如

type
  TFooEvent = procedure(ANumber : double; Sender : TObject) of object;

然后您可以使用click事件发送数据:

if Assigned(FButton1Clicked) then FButton1Clicked(1.23, Button1);