2011-08-24 26 views
2

我有大量非常相似的用戶控件。他們有很多共同的行爲。我一直在使用一個基本類,它具有常見的東西,然後根據需要專門設計類。正確的架構來擴展WinForm UserControl基類嗎?

class BaseControl : UserControl 
{ 
    // common 
} 

class RedControl : BaseControl 
{ 
    // specialized 
} 

class BlueControl : BaseControl 
{ 
    // specialized 
} 

等等

,直到我需要開始插入或更改包含在BASECONTROL子控件的佈局這工作得相當好。例如,RedControl需要將一個Button添加到基本控件的特定面板。在其他情況下,我需要更改其他基本子控件的大小或佈局。

當我嘗試下面的代碼,我沒有看到在運行時任一按鈕...

public partial class RedControl : BaseControl 
{ 
    public RedControl() 
    { 
    InitializeComponent(); 

    addButtonToBase(); // no button shows up 
    this.PerformLayout(); 
    } 
    void addButtonToBase() 
    { 
    Button button = new Button(); 
    button.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left))); 
    button.Location = new System.Drawing.Point(3, 3); 
    button.Size = new System.Drawing.Size(23, 23); 
    button.Text = "My Button"; 

    baseSplitContainer.Panel1.Controls.Add(button); // protected child control in base 
    } 
    // ... 
} 

可以使按鈕顯示爲baseSplitContainer的孩子,如果我做addButtonToBase()虛並手動將其添加到BaseControl的InitalizeComponent()中的生成代碼中。 BaseControl的佈局仍在繼續,您可以在C#.Net中的構造函數中調用虛函數....

所以即使它工作,它也不是一個好的解決方案。首先,當我在VS設計器中編輯BaseControl時,IntializeComponent中對addBaseControl()的調用被移除,對於構造函數中的另一個調用虛擬函數來說,這會很危險。

我認爲我需要得到基本控制的佈局在導出的控制再次發生...... 我試過,但無論是做錯了或者它不會工作...

BTW是的,我知道WPF擅長這一點。由於其他系統的限制,不能使用它。

回答

0

我想你只是想念一些東西來調用基本的init邏輯來創建控件,然後你的改變被覆蓋。嘗試調用它像

public RedControl() 
: base() 
    { ... } 

OR

public RedControl() 
    { 
    base.InitializeComponent(); 
    InitializeComponent(); 

    addButtonToBase(); // no button shows up 
    this.PerformLayout(); 
    } 
+1

當一個派生控件被構造時,總是調用基類構造函數。沒有必要調用base.InitializeComponent()它也沒有解決佈局問題。 – meissnersd

4

原來修改基本控制佈局的正確方法是重寫從Control.OnLayout()

佈局通話所以像

public RedControl() 
{ 
    //.... 
    protected override void OnLayout(LayoutEventArgs e) 
    { 
     addButtonToBase(); // modify base layout 
     base.OnLayout(e); 
    } 
}