Danielle
Danielle

Reputation: 490

WinForms Inheritance InitializeComponent

I have a BaseForm that specifies several protected controls which are initialized in BaseForm.InitializeComponent(). I've made these controls protected so that I can access the values of dropdowns, etc, in my DerivedForm. Making these controls accessible to DerivedForm causes the Designer to include them in DerivedForm.InitializeComponent(), which resets them, thus undoing any additional work I've done in the BaseForm constructor.

Is there a way to access my BaseForm controls in DerivedForm, but not have them initialized a second time?

    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
    }

Upvotes: 2

Views: 2563

Answers (2)

Peter Duniho
Peter Duniho

Reputation: 70652

I've made these controls protected so that I can access the values of dropdowns

There's your problem.

Don't make those controls protected. Keep them private to the base class. Expose them to subclasses exactly as you would publicly: by wrapping access to the controls in public properties that allow access to only the aspects of those controls that need to be accessed.

For example:

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.
}

Note that if things like ComboBox uses e.g. enum values, you can make a property like SelectedValue instead, having the enum type and cast when returning from the comboBox1.SelectedValue property.

Note also that another way to approach this type of design issue is to author UserControl objects instead of forms, and use composition to build up the task-specific forms. This avoids inheritance altogether.

Upvotes: 1

Perspicathir
Perspicathir

Reputation: 26

BaseForm's implementation of InitializeSettings:

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

DerivedForm's implementation of InitializeSettings:

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

And call of InitializeSettings() in your DerivedForm's constructor will set your settings.

Okay, the goal was not clear for me.

If you want to have just 1 initialization of Settings, do not apply them in constructor. Basically, you should use the

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

The second way to solve the problem is to not even have parameterized constructor and to call InitializeSettings outside after creation of form by default constructor.

Upvotes: 0

Related Questions