将单个表单重置为其初始状态

wlwcrazw  于 2022-10-16  发布在  其他
关注(0)|答案(2)|浏览(168)

我在一个项目中有多个表单:frmBookingfrmWelcomefrmAdmin。我想通过单击一个按钮来重置frmBooking(即,将其重置为初始状态,就好像它是用所有组件创建的一样)。我试着做了以下事情:

frmBooking.Destroy;
Application.CreateForm(TForm, frmBooking);
frmBooking.Show;

然而,结果是它只创建了一个空白表单,而不是将该表单重置为其初始状态。
我可以做些什么来重置表单?

bfrts1fy

bfrts1fy1#

根据您最初的方法,我编写了一些代码。

var
  theOwner: TComponent;
begin
  { make sure that we don't kill ourselves. 
    can be omitted if we are sure it cannot happen. }
  theOwner := Owner;
  while theOwner <> nil do begin
    if theOwner = frmBooking then
      raise Exception.Create('cannot recreate owner form');
    theOwner := theOwner.Owner;
  end;

  { find out who must be the owner of the newly created instance }
  theOwner := frmBooking.Owner;
  frmBooking.Free;
  frmBooking := TfrmBooking.Create(theOwner);
  frmBooking.Show;
end;
sgtfey8w

sgtfey8w2#

要刷新由另一个表单创建的表单,您需要做几件事。
首先,知道谁拥有什么。Form1是否拥有Form2,或者Form1只是为应用程序创建它?如果它嵌入在Form1中,就像Form1.Panel1或其他什么东西,那么Self或Panel可以是父级,但如果我们希望它显示为一个单独的窗口,那么Self是不正确的,我们可能需要Application作为我们的父级,就像您在My TForm2.Create(Application)中看到的那样
其次,您需要处理来自Form2或其他控制刷新决策的服务的刷新请求。为此,最简单的方法是使用将消息发送到Form1的事件,或者如果其他对象做出了该决定,则事件过程的处理方式从该对象类似于Form2,它开始关闭,然后Form2触发第二个事件,如我的示例,对于最初创建Form2的人,如Form1!您可以使用sendMessage或postMessage,但这超出了必要的范围。表单已经内置了TNotifyEvent,但让我们创建一个新的TNotifyEvent来显示它是如何完成的。多个事件的一个例子是:想象一个MainForm有两个选项卡控件,rTab和LTab,每个都填充了5个选项卡,每个Tab在源代码中是一个表单。RTab2被编辑,它用一个事件通知Main,然后Main通知LTab2重新加载数据并将其显示在网格中。
最后,刷新的触发器可以是Form2中的任何位置。在我的示例中,我们通过单击按钮来强制它,这与X按钮没有什么不同,只是我们继续执行Form1的事件处理程序。这将告诉Form1在旧对象自我销毁时开始重新创建新对象。无论您是在EVEN处理程序中创建新的数据对象,调用额外的Form1函数和过程来完成该操作,还是只是让Form2的CREATE重新填充,都由您自己决定。
如果不是这样,我的示例在初始创建Form2时展示了如何处理它。
在我的示例中,不需要特殊的销毁或FreeAndNil,但您可能需要覆盖和重新引入过程。
我只有两个带有按钮的表单,所以除了设置按钮的onClick之外,没有什么特别的。最好检查一下事件调用是否定义为防止错误,即使它不是可选的……

if Assigned(EventProcedureName) then
begin
  EventProcedureName(Self);
end;

TForm1:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    FCounter: Integer;
  public
    procedure RefreshChildEventHandler(Sender: TObject);
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  System.UITypes, Unit2;

{$R *.dfm}

procedure TForm1.RefreshChildEventHandler(Sender: TObject);
var
  childForm: TForm2;
  frmType: string;
begin
  try
    childForm := TForm2.Create(Application);
    case FCounter of
      0:
        begin
          childForm.Color := TColorRec.White;
          FCounter := 1;
        end;
      1:
        begin
          childForm.Color := TColorRec.Blue;
          FCounter := 2;
        end;
      2:
        begin
          childForm.Color := TColorRec.Red;
          FCounter := 0;
        end;

    end;

    childForm.RefreshMeEvent := RefreshChildEventHandler;
    childForm.Show;
  except
    raise;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  // Why not use our procedure on initial create?
  RefreshChildEventHandler(Self);
end;

end.

TForm2:

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls;

type
  TForm2 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    FOnChange: TNotifyEvent;
    { Private declarations }
  public
    { Public declarations }
    property RefreshMeEvent: TNotifyEvent
      read FOnChange
      write FOnChange;
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  Self.Close;
  Self.RefreshMeEvent(Self);
end;

end.

相关问题