2017-03-21 44 views
0

我有一個BaseForm,指定在BaseForm.InitializeComponent()中初始化的幾個受保護的控件。我已經使這些控件受到保護,以便可以在我的DerivedForm中訪問下拉列表等。使這些控件可以被DerivedForm訪問會導致設計器將它們包含在DerivedForm.InitializeComponent()中,它們將它們重置,從而撤消我在BaseForm構造函數中完成的任何其他工作。WinForms繼承InitializeComponent

有沒有辦法在DerivedForm中訪問我的BaseForm控件,但沒有第二次初始化?

public SettingsDialogBase(Settings settings) 
    { 
     InitializeComponent(); 

     // Additional work which initializes dropdowns, etc 
     InitializeSettings(); 
    } 

    public SettingsDialog(Settings settings) : base(settings) 
    { 
     InitializeComponent(); 
     // InitializeSettings() rendered useless on controls that are set to protected 
     // because SettingsDialog.InitializeComponent() included them automatically 
    } 
+0

[Windows窗體繼承]可能的重複(http://stackoverflow.com/questions/826425/windows-form-inheritance) –

+0

嗯我不這麼認爲。我的BaseForm和DerivedForm都成功地調用了它們自己的InitializeComponent()方法。問題是BaseForm構造函數在InitializeComponent()後面的控件上做了額外的工作,並且因爲它們是受保護的控件,DerivedForm在調用它自己的InitializeComponent()方法時撤消了所有的工作。 – Danielle

+0

從派生類的構造函數中移除'InitializeComponent()' – Fabio

回答

1

我做了這些控件保護,使我可以訪問的下拉列表中的值

有你的問題。

不要使這些控件protected。讓他們private到基類。將它們公開爲子類:公開屬性中的控件訪問權限允許訪問需要訪問的那些控件的方面。

例如:

class BaseForm : Form 
{ 
    public string PromptText 
    { 
     get { return textBox1.Text; } 
     set { textBox1.Text = value; } 
    } 

    public int SelectedIndex 
    { 
     get { return comboBox1.SelectedIndex; } 
     set { comboBox1.SelectedIndex = value; } 
    } 

    // etc. 
} 

注意,如果之類的東西ComboBox使用例如枚舉值,您可以創建像SelectedValue這樣的屬性,使用枚舉類型並在從comboBox1.SelectedValue屬性返回時執行強制轉換。

另請注意,解決此類設計問題的另一種方法是編寫UserControl對象而不是表單,並使用組合構建特定於任務的表單。這完全避免了繼承。

+0

我嘗試訪問的大部分字段都是ComboBox控件,所以這將工作得很好。我還發現,向其他控件(如GroupBox)添加[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]似乎可以防止它在DerivedForm.InitializeComponent()中變得太瘋狂了。 – Danielle

0

基本形式的實現InitializeSettings的:

protected virtual void InitializeSettings(Settings settings) 
{ 
    //initialization of settings 
} 

DerivedForm的實現InitializeSettings的:

protected override void InitializeSettings(Settings settings) 
{ 
    base.InitializeSettings(x); 
    //reinitialization of settings 
} 

而且InitializeSettings的()調用在DerivedForm的構造函數將設置你的設置。

好的,我的目標不明確。

如果你想只有1個設置的初始化,不要在構造函數中應用它們。基本上,你應該使用

protected override void OnLoad(EventArgs e) 
{ 
    base.OnLoad(e); 
    //initialization of settings 
} 

第二種方式來解決問題是甚至沒有參數的構造函數,並用默認構造函數創建表單後的外部調用InitializeSettings。

+0

所以我的組件仍然初始化兩次,然後設置被初始化兩次以彌補它?我真的在尋找解決方案,在這裏初始化組件和設置一次。具體來說,BaseForm初始化其組件,DerivedForm僅初始化其組件,而不初始化BaseForm組件。 – Danielle

+0

我已經根據你的評論更新了我的答案 – S0zidatel