2011-10-19 62 views
2

好吧,這是事情,我有調用OrderForm.Show()的MainForm。 現在我想用一個按鈕在MainForm中調用公共函數,但我不能。如何從子窗體中引用窗體?

這裏是MainForm中的代碼:

public partial class frmMain : Form 
{ 
    public frmMain() 
    { 
     InitializeComponent(); 
    } 

    // Main form 
    private void MainFrm_Load(object sender, EventArgs e) 
    { 
     FormOrder frmO = new FormOrder(); 

     frmO.Show(); 
    } 

    public void Refresh() 
    { 
     // some action 
    } 
} 

而在OrderForm我這樣做:

public partial class FormOrder : Form 
{ 
    public FormOrder() 
    { 
     InitializeComponent(); 
    } 

    private void ShowForm() 
    { 
     // some action 
    } 

    private void btnCopy_Click(object sender, EventArgs e) 
    { 
     Form form = Form.ActiveForm as frmMain; 

     if (form != null) 
     { 
      form.Refresh(); 
     } 

    } 
} 

所以在節目我跑MainForm.Show(),然後加載OrderForm。然後當我點擊複製按鈕時,它將在MainForm中運行公共功能刷新。但我不能讓它工作,它總是返回null:

Form form = Form.ActiveForm as frmMain; 

所以我怎樣才能真正得到有效形式,是另一種解決方案?或者我弄錯了? 在此先感謝您的答案:)

+1

你應該改變標題。你想從一個子表單引用一個表單。主要的形式不是在你想引用它的時候的活動形式(在框架中)。 – TheBlastOne

回答

4

你得到一個空,因爲您的活動形式是一個你在和它不是frmMain類型。 (我認爲你實際上可能會混淆父表單的活動表單?)

有這樣的可能方法。你可以讓你的單身人士成爲一個單身人士,但這很奇怪,也很醜陋,而且不會推遲,或者你可以以某種方式將它引用給孩子。這裏有一個簡單的方法:

public partial class frmMain : Form 
{ 
    public frmMain() 
    { 
     InitializeComponent(); 
    } 

    // Main form 
    private void MainFrm_Load(object sender, EventArgs e) 
    { 
     FormOrder frmO = new FormOrder(this); // pass a ref of self 

     frmO.Show(); 
    } 

    public void Refresh() 
    { 
     // some action 
    } 
} 

而且在OrderForm:

public partial class FormOrder : Form 
{ 
    private frmMain _parent; // create a field that refers to the parent 
    public FormOrder(frmMain parent) // mod the constructor 
    { 
     if (parent == null) throw new NullReferenceException("Can't be NULL!!!"); // check clause 

     _parent = parent; // assign the ref of the parent 

     InitializeComponent(); 
    } 

    private void ShowForm() 
    { 
     // some action 
    } 

    private void btnCopy_Click(object sender, EventArgs e) 
    { 
      _parent.Refresh(); // make the call to parent 
    } 
} 

你可以利用可用的接口,但總的想法是相同的這更好的。

+0

謝謝,我選擇這個答案,因爲它符合我目前的情況:)感謝所有答案:) –

1

我不會建議您採取路線訪問活動窗體來完成您的目標。您需要做的是將MainForm的引用傳遞給OrderForm,因此OrderForm可以使用引用來調用MainForm上的任何方法。

private void MainFrm_Load(object sender, EventArgs e) 
{ 
    FormOrder frmO = new FormOrder(); 
    frmO.MainForm = this; 

    frmO.Show(); 
} 

而且在FormOrder類,你應該添加一個新的屬性的MainForm,並使用屬性來引用調用形式: -

public partial class FormOrder : Form 
{ 
    public Form MainForm; 

    public FormOrder() 
    { 
     InitializeComponent(); 
    } 

    private void ShowForm() 
    { 
     // some action 
    } 

    private void btnCopy_Click(object sender, EventArgs e) 
    { 
     if (MainForm != null) 
     { 
      MainForm.Refresh(); 
     } 

    } 
} 
+0

這也可以。我喜歡使用構造函數來更好地傳遞主窗體,因爲沒有辦法忘記設置屬性,而且您不必檢查null。如果不傳入對主窗體的引用,則無法創建訂單表單。您可以傳遞null,但可以在構造函數中執行檢查,並且強制實施非null主表單引用的規則。 –

+0

你使用構造函數的方式很好。這就是在Delphi中完成的方式,其中大多數TComponent的構造函數都將AParent作爲參數。我對.NET不太熟悉,我發現默認的構造函數沒有這個。 –

1

您需要引用mainForm以外的mainForm和/或mainForm的按鈕單擊事件。你可以用不同的方式做到這一點。創建一個具有對mainForm的引用的靜態類,創建一個具有對mainForm click事件的委託的靜態類,將mainForm傳遞給childForm的構造函數,將委託傳遞給childForm的構造函數。創建一個處理click事件的靜態方法,然後在childForm中使用它。

這一切都取決於你想要做什麼,你需要做什麼以及你如何去做。

+0

+1指出其他人沒有提到的東西。 – TheBlastOne

1

雖然其他答案是絕對正確的,我想建議一個更容易,但「髒」的方式來做到這一點。

每個組件都有一個Tag屬性,您可以存儲任何用戶定義的值或引用。的想法是保存在第二種形式的Tag到主窗體的引用,從按鈕單擊事件處理程序訪問它。

好事是,你不必寫很多代碼,或任何數據結構。

髒東西它是,無論是在運行時框架,也不在編譯時,編譯器有什麼你.Tag存儲任何想法,因爲它沒有輸入正確,你正在做一個類型轉換,這取決於你事先在那裏存儲正確的值。 如果您在那裏存儲錯誤的值,則可能很難調試原因,因爲症狀不表示將錯誤值置入Tag的位置。因此,野生Tag usuage在一個團隊的程序員是一件好事,如果你想生出許多意想不到難以檢測和修復bug :)

而且,只有一個Tag每個組件。如果您需要多個用戶定義的值,那麼您最終可能會創建一個自定義數據結構,然後Tag可以引用它,但這可能比其他所有建議都要大。

public partial class frmMain : Form 
{ 
    public frmMain() 
    { 
     InitializeComponent(); 
    } 

    // Main form 
    private void MainFrm_Load(object sender, EventArgs e) 
    { 
     FormOrder frmO = new FormOrder(); 

     frmO.Tag=this; 
     frmO.Show(); 
    } 

    public void Refresh() 
    { 
     // some action 
    } 
} 


public partial class FormOrder : Form 
{ 
    public FormOrder() 
    { 
     InitializeComponent(); 
    } 

    private void ShowForm() 
    { 
     // some action 
    } 

    private void btnCopy_Click(object sender, EventArgs e) 
    { 
     Form form = Tag as frmMain; // form now references the main form 

     if (form != null) 
     { 
      form.Refresh(); 
     } 

    } 
} 

一個很好的例子一個快速和骯髒的解決方案,以限制這樣的內在,你通常識別它們,只有當它是太晚了 - 這就是爲什麼我首先要告訴;)

+0

嗯,這是有趣的事情:但我使用其他答案。 thx :) –

+0

沒問題。接受什麼幫助! – TheBlastOne

相關問題