2013-07-14 150 views
0

編輯身體瞭解更多詳情訪問StringGrid。從另一種形式

我有一個名爲ENP的形式,在EnpView單元定義。該ENP形式,創建並從點擊主窗體(TPrincipal)工具欄項目的處理程序事件中。

procedure TPrincipal.ENP1Click(Sender: TObject); 
begin 
    TENP.Create(self).Show(); 
end; 

Enp表單知道(在公共聲明中)clearGrid()消息。

ENP形式有TStringGrid稱爲StringGrid。還有一個叫做「添加」的按鈕。當點擊「添加」按鈕時,創建並顯示其他窗體:EnpViewAdd單元中定義的AddEnp窗體。

procedure TENP.opAgregarClick(Sender: TObject); 
begin 
    TAddEnp.Create(self).Show(); 
end; 

AddEnp表單,有任何TEdits。輸入的值必須在EnpView.StringGrid中添加。

我試試這個:

implementation 

uses 
    EnpView, Main; 
procedure TAddEnp.AgregarClick(Sender: TObject); 
begin 

    { Agrego el nodo xml } 
    Globals.Xml.agregarMuestra(muestra.Text); 
    Globals.Xml.insertEnp(muestra.Text,golpes.Text,metros.Text); 

    { Send messages to EnpView Form } 
    ENP.clearGrid(); 
    ENP.populateGrid(); 

end; 

ClearGrid的消息在1號線發生故障,訪問衝突:如果在類內發送

procedure TENP.clearGrid(); 
begin 
    Self.StringGrid.RowCount := 2; 
    Self.StringGrid.Rows[1].Clear(); 
end; 

的clearGrid方法的工作原理。有任何想法嗎 ?。

+0

ENP被分配? – bummi

+0

ENP是第一單元內的一種形式。 ENP在執行第二個表單時已經創建。 – ramiromd

+0

「stringgrid」的聲明是什麼?是否分配?將斷點放在問題行上,並在執行之前評估'指針(Self)'和'指針(Self.stringgird)'是否有合理的值 –

回答

1

創建一個命名屬性,例如, ENPForm在TAddENP中,並分配E NP形式創建它之後。聲明如下:

TAddENP = class(TForm) 
private 
    FENPForm: TENP; 

// all of your already existing declarations 

public 
    property ENPForm: TENP read FENPForm write FENPForm; 
end; 

既然您有可能參考ENP表格,您可以隨意使用它。

在創建TAddENP形式,具體操作如下:

procedure TENP.opAgregarClick(Sender: TObject); 
var 
    addForm: TAddENP; 
begin 
    addForm := TAddEnp.Create(Self); 
    addForm.EnpForm := Self; 
    addForm.Show; 
end; 

現在創建的第二個形式,並賦予它一個安全參考第一個。他們現在可以安全地互相交談。

我建議你避免讓一個表單操作其他人的組件,因爲這會增加它們之間的依賴關係。相反,聲明公共方法來做到這一點,所以表單將取決於他們的接口,而不是他們的實現。

我希望這會有所幫助。

+0

你的答案正常工作!謝謝 ! – ramiromd

0

從你的問題(我加code-style,以使其更清晰):

我有一個名爲ENP形式,在EnpView單元定義。該ENP形式,創建 ,並從主窗體點擊工具欄項 (TPrincipal)的處理程序事件中。

procedure TPrincipal.ENP1Click(Sender: TObject); 
begin 
    TENP.Create(self).Show(); 
end; 

這無助與ENP表單變量。
您創建了一個TENP表單類的實例,並使用Show顯示它,但未分配ENP變量。
由於每個按鈕單擊都會創建一個新實例(因此您有多個實例TENP),您無法將實例分配給ENP變量。

然後,您創建一個TAddEnp實例和(從未分配的ENP變量)的旋轉依賴關係。
您可以通過創建一個TAddEnp實例(爲什麼TAddEnp這裏,而不是TAddENP做到這一點?它使用Show(讓用戶有機會回到TENP實例,再次單擊opAgregar按鈕創建的TAddEnp多個實例))顯示:

procedure TENP.opAgregarClick(Sender: TObject); 
begin 
    TAddEnp.Create(self).Show(); 
end; 

其次是具有TAddEnp取決於ENP變量:

procedure TAddEnp.AgregarClick(Sender: TObject); 
begin 
//... 
    ENP.clearGrid(); 
    ENP.populateGrid(); 
end; 

這確實會失敗:

ClearGrid消息在管線1出現故障,與訪問衝突:

procedure TENP.clearGrid(); 
begin 
    Self.StringGrid.RowCount := 2; 
    Self.StringGrid.Rows[1].Clear(); 
end; 

的原因是,ENP未分配(缺省它將nil),所以內部clearGrid,所述Self也將是nil

解決方案,您可以實現

  1. 保持TENPTAddEnp一個單一實例,使用ShowModal強制方式,以防止用戶點擊相同的按鍵多次。
  2. 保持您的現有Show行爲,但將每個TAddEnp實例綁定到它創建的TENP實例。

對於第一種解決方案,你的代碼將變成這樣:

procedure TPrincipal.ENP1Click(Sender: TObject); 
begin 
    ENP := TENP.Create(Application); 
    ENP.ShowModal(); 
    ENP.Release(); 
    ENP := nil; 
end; 

procedure TENP.opAgregarClick(Sender: TObject); 
begin 
    AddEnp := TAddEnp.Create(Application); 
    AddEnp.ShowModal(); 
    AddEnp.Release(); 
    AddEnp := nil; 
end; 

第二個將採取更多的努力,因爲你需要防止利用現有的變量。

  • 刪除ENP變量。
  • 刪除AddENP變量。

修復self - 在方法

procedure TPrincipal.ENP1Click(Sender: TObject); 
begin 
    TENP.Create(Self).Show(); 
end; 

procedure TENP.opAgregarClick(Sender: TObject); 
begin 
    TAddEnp.Create(Self).Show(); 
end; 

這裏添加的依賴>Self

procedure TAddEnp.AgregarClick(Sender: TObject); 
var 
    ENP: TENP; 
begin 
//... 
    ENP := Owner as TENP; // Owner will be of type TENP because of the Create(Self) in the ENP1Click method 
    ENP.clearGrid(); 
    ENP.populateGrid(); 
end;