2011-08-09 15 views
0

我不確定這是否可行,但我希望能夠做的是讓所有的父類基類運行基類中定義的方法,而不在子類中明確調用它。在子構​​造函數的InitializeComponent完成後沒有在子類中隱式調用的方法運行

換句話說,我想實現的是這樣的:

public class Parent 
{ 
    public Parent() 
    { 
     InitializeComponent(); 
     Setup(); // not run here if this instance is a child of parent 
    } 

    protected void Setup() 
    { 
     // code that depends on InitializeComponent being called in 
     // both the parent and any Child's classes 
    } 
} 

public class Child : Parent 
{ 
    public Child() 
    { 
     InitializeComponent(); 
     //Setup(); is invoked here, without having to explicitly 
     // invoke in all children of Parent 
    } 
} 

是否有可能使這種行爲,或者也許可以面向方面編程是一種方式來實現這一模式?

回答

4

你可以改寫父窗體的Form.OnLoad方法;它保證在表單顯示前被調用。

protected override void OnLoad(EventArgs e) 
{ 
    Setup(); 

    base.OnLoad(e); 
} 
0

Child的構造函數會自動調用Parent的構造函數(實際上在調用它自己的代碼之前),所以在上面的情況中,安裝程序將始終在Child類中調用(並且InitializeComponent將被調用兩次) 。

1

我覺得你只是想重寫OnLoad方法:

public class Parent 
{ 
    public Parent() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnLoad(EventArgs e) 
    { 
     // put initialization code here 

     base.OnLoad(e); 
    } 
} 

當兩個父和子組件初始化它被調用。
不要忘記致電base.OnLoad,以便Load事件處理程序(如果有)接收事件。

0

Load事件或OnLoad中的運行代碼通常是最差的解決方案。

如果你想在表單加載後運行一次代碼,你可以使用Shown事件,否則你的表單看起來很滯後而且沒有響應,你有很長時間的運行代碼(控件會一個接一個地顯示出來)。

如果您確實想在子構造函數之後但在加載事件之前運行代碼,則重寫OnHandleCreated是您的最佳選擇。

但是:(至少)還有一件事情不會起作用。我有一個表單基類,用於設置特定的啓動位置/大小,而不管子表單定義的是什麼。我所做的每一次努力都失敗了,或者在錯誤的位置看到了一秒鐘的形式。這是我如何解決它:

public class MyForm : Form 
{ 
    private Size defaultSize; 
    public MyForm() 
    { 
     InitializeComponent(); 
     this.defaultSize = this.Size; 
     this.fireOnBeforeLoad = true; 
    } 
    public new void ResumeLayout(bool performLayout) 
    { 
     base.ResumeLayout(performLayout); 

     if (fireOnBeforeLoad) 
     { 
      fireOnBeforeLoad = false; 
      OnBeforeLoad(); 
     } 
    } 
    protected virtual void OnBeforeLoad() 
    { 
     form.WindowState = FormWindowState.Normal; 
     form.Size = defaultSize; 
     form.FormBorderStyle = FormBorderStyle.FixedDialog; 
     var area = Screen.FromControl(form).WorkingArea; 
     form.Size = defaultSize; 
     form.Location = new System.Drawing.Point(
      (int)(area.Width - form.Width)/2, 
      (int)(area.Height - form.Height)/2); 
    } 
} 

這裏是棘手的部分:後喲設置大小,它在某種程度上大幹快上的負載過程中的一些點恢復。如果您致電Screen.FromControl(form),也會發生同樣的情況。我猜想,因爲Screen.FromControl最終會調用Screen.FromHandle,這將導致創建句柄。但我想它也會做其他事情,因爲如果我在OnHandleCreated方法中運行上述代碼(當然在調用base.OnHandleCreated之後),它不會得到期望的結果。因此,我在Screen.FromControl之後再次設置大小,最後一行只是將屏幕居中放置。

相關問題