2015-05-06 81 views
0

我有動態加載(並銷燬)不同類型的用戶控件到需要的表單上的代碼。用戶控件使用其父級的屬性將某些值加載到控件中,如文本框和複選框。問題是,在該行:從孩子訪問ParentForm並確保添加孩子

activeControl = new userControl1(params...); 

我的構造函數顯然會嘗試還不存在裝載場(它們屬於父窗體),因爲它沒有被添加到父窗體,直到在userControl1創建後。

我試着用用戶控件的ParentChanged事件來解決這個問題,所以它在加載字段之前一直等到它的父對象被設置。這裏的問題是,當我銷燬userControl1並創建一個userControl2時,父級更改並嘗試從null ParentForm(我原本的確切問題)中加載字段。

是否有解決此問題的首選方法?顯然,我可以添加類似

if(this.ParentForm == null) { return; } 

到ParentChanged事件或類似的規定。但是,這感覺既優雅也不安全。我俯瞰一些事件或完成這一首選方式?

+0

經常在事件檢查null是一個好主意(不錯的想法)。在InitializeComponent()事件觸發期間,必須被忽略。這些假事件期間列表框和組合框的行索引爲-1,並且在事件處理程序中檢查索引> = 0是正常的。 – jdweng

+0

你從「ParentForm」訪問的實際內容是什麼?如果您將'ParentForm'強制轉換爲其他子類型,通常在用戶控件內部訪問父表單並不是一個好主意。 –

回答

0

雖然不一定是壞的檢查null引用和轉移代碼acco (例如,不要試圖引用缺失的對象),這裏更好的方法是將你的UserControl類與父母分開。

也就是說,這些UserControl類根本不應該有任何意識到他們的父表單類型。否則就是否定OOP的一個主要優點:代碼重用。使用您當前的設計,即使讓它在沒有崩潰的情況下工作,除非在此特定父級表單類型的上下文中,否則您將永遠無法使用這些UserControl對象。

今天你可能會認爲沒關係,你永遠不會想在任何其他環境中使用它們。但未來很難預測。例如,您可能會決定要在父表單上使用這些相同的UserControl對象。

你應該做的是通過公共屬性暴露UserControl狀態,然後允許父表單根據需要初始化這些狀態。

這裏是一個非常簡單的例子(我省略了設計師創建的代碼…我認爲你可以從現場的名字我的意思推斷):

partial class UserControl1 : UserControl 
{ 
    /* ... */ 

    public bool IsMyFlagChecked 
    { 
     get { return checkBox1.Checked; } 
     set { checkBox1.Checked = value; } 
    } 

    /* ... */ 
} 

partial class ParentForm : Form 
{ 
    /* ... */ 

    private void SomeMethodThatAddsUserControl1() 
    { 
     UserControl1 uc1 = new UserControl1; 

     uc1.IsMyFlagChecked = 
      this.SomeParentFormPropertyUserControl1UsedToReferenceDirectly; 
     // other initialization for uc1... 

     Controls.Add(uc1); 
    } 

    /* ... */ 
} 

(注意,如果沒有a good, minimal, complete code example,說明你的問題,我無法提供比上面更詳細的代碼示例,如果這似乎不能解決您的問題,請對其進行編輯,以便提供更多詳細信息,包括更好的代碼示例)。