darx
darx

Reputation: 1657

Accessing outer classes fields from inner class

I use custom renderer for ContextMenuStrip. It works fine, but I can't figure out how can I use fields from outer class Form1 inside of class MyColors? I should get customColor from Form1 instead of "hardcoded" Color.Green. How can I achieve this?

public partial class Form1
{
    private Color customColor = Color.Red;

    private class MyRenderer : ToolStripProfessionalRenderer
    {
        public MyRenderer() : base(new MyColors()) { }
    }

    private class MyColors : ProfessionalColorTable
    {
        public override Color MenuItemSelected
        {
            get { return Color.Green; }
        }
    }
}

Thanks in advance.

Upvotes: 1

Views: 438

Answers (2)

Matt Dillard
Matt Dillard

Reputation: 14863

In general, I agree with other posters that a class should stand alone. I think it gets a little fuzzier when dealing with a private class, though.

In the few cases I've needed something like this, I pass the parent object into the private class' constructor:

public partial class Form1
{
    public Color customColor = Color.Red;

    private class MyRenderer : ToolStripProfessionalRenderer
    {
        public MyRenderer(Form1 form) : base(new MyColors(form)) { }
    }

    private class MyColors : ProfessionalColorTable
    {
        Form1 _form;

        public MyColors(Form1 form)
        {
            _form = form;
        }

        public override Color MenuItemSelected
        {
            get { return _form.customColor; }
        }
    }
}

Note that I had to make Form1.customColor public for this to work. That's a bit smelly, especially since it can now be assigned from the outside. In real work, I'd make it a property with a public getter and a private setter, so outside classes couldn't modify it.

Upvotes: 4

Andrew
Andrew

Reputation: 7880

You would be breaking encapsulation that way. If you need a contained class to know something from its containing class, you should provide such information in the contained class' constructor.

Otherwise, you would be letting another class change your class' properties, losing control over what happens inside Form1.

Considering your code, it seems ProfessionalColorTable has a parameterless constructor, so you should include a validation in case MyColors' private variable pointing to the containing class' color is not set (as a result of using the wrong constructor).

Upvotes: 1

Related Questions