我在一個專案中有多種形式:frmBooking, frmWelcome, frmAdmin. 我想frmBooking通過單擊一個按鈕來重置(即,將其重置為初始狀態,就好像它是用所有組件創建的一樣)。我嘗試執行以下操作:
frmBooking.Destroy;
Application.CreateForm(TForm, frmBooking);
frmBooking.Show;
然而,結果是它只是創建了一個空白表單,而不是將表單重置為其初始狀態。
我可以做些什么來重置表格?
uj5u.com熱心網友回復:
根據您最初的方法,我整理了一些代碼。
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;
uj5u.com熱心網友回復:
要重繪 由另一個表單創建的表單,您需要做幾件事。
首先,知道誰擁有什么。Form1 擁有 Form2 還是 Form1 只是為應用程式創建它?如果它嵌入在 Form1 中,如 Form1.Panel1 或其他東西,則 Self 或 Panel 可以是父級,但如果我們希望它顯示為單獨的視窗,則 Self 不正確,我們可能需要 Application 作為父級你在我的 TForm2.Create(Application) 中看到
其次,您需要處理來自 Form2 或其他控制重繪 決定的服務的重繪 請求。為此,最簡單的方法是使用向 Form1 發送訊息的 EVENT,或者如果其他人做出該決定,事件程序的處理方式與從該物件到 Form2 的處理方式類似,后者開始關閉,然后 Form2 觸發第二個像我的例子一樣的事件,對于像 Form1 一樣首先制作 Form2 的人!您可以使用 sendmessage 或 postmessage,但這超出了必要的范圍。表單已經內置,但讓我們創建一個新的 TNotifyEvent 來展示它是如何完成的。多個事件的一個例子是:想象一個 MainForm 有兩個選項卡控制元件,RTab 和 LTab 每個填充 5 個選項卡,每個選項卡是源代碼中的一個表單。RTab2 被編輯,它通知 Main 一個事件,
最后,重繪 的觸發器可以是 Form2 中的任何地方。在我的示例中,我們通過與 X 按鈕沒有區別的按鈕單擊來強制它,除了我們跟進 Form1 的事件處理程式的執行。這將告訴 Form1 開始重新創建一個新物件,而舊物件正在破壞自己。無論您是在偶數處理程式中創建新資料物件、呼叫其他 Form1 函式和程序來執行此操作,還是只是讓 Form2 的 Create repopulate 由您決定。
如果不是這種情況,我的示例將在 Form2 的初始創建中顯示如何處理它。
在我的示例中,不需要特殊的 Destroy 或 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.
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/509889.html
