Reputation: 5
I have an inner class to contain methods of my project; and I want to use the Form
class event handlers to call my methods from the inner class; but I am having trouble accessing members of the outer class such as label1
, label2
, label3
etc.
How do I access a field of an outer class?
I'm trying to make an association inside the constructor :
public partial class Form1 : Form
{
// declare inner class here
public MachineClass machineObj = new MachineClass();
public class MachineClass
{
int fruit1, fruit2, fruit3, fruitvalue1, fruitvalue2, fruitvalue3;
public void spinslot()
{
Random player = new Random();
fruit1 = player.Next(10);//generates a number between 0 and 9
fruit2 = player.Next(10);//generates a number between 0 and 9
fruit3 = player.Next(10);//generates a number between 0 and 9
fruitvalue1 = fruit1 + 1;//
fruitvalue2 = fruit2 + 1;//
fruitvalue3 = fruit3 + 1;//
label1.ImageIndex = fruit1;//display image in label - uses image list
label2.ImageIndex = fruit2;//display image in label - uses image list
label3.ImageIndex = fruit3;//display image in label - uses image list
}
}
}
Upvotes: 0
Views: 1472
Reputation: 117154
Here is what you really need to do to make this work and to do so with a better OO design.
First-up, define the internal MachineClass
like this:
public class MachineClass
{
private int fruit1, fruit2, fruit3;
public delegate void FruitUpdate(int value);
public event FruitUpdate FruitUpdate1;
public event FruitUpdate FruitUpdate2;
public event FruitUpdate FruitUpdate3;
public void spinslot()
{
Random player = new Random();
fruit1 = player.Next(10);
fruit2 = player.Next(10);
fruit3 = player.Next(10);
if (this.FruitUpdate1 != null) this.FruitUpdate1(fruit1);
if (this.FruitUpdate2 != null) this.FruitUpdate2(fruit2);
if (this.FruitUpdate3 != null) this.FruitUpdate3(fruit3);
}
}
The FruitUpdate
delegate allows the definition of three events that can let external users of this class know when updates to the fruit values occur. When updates to the fruit values occur we check that there are handlers attached to the event and then just call the events. The MachineClass
does not need to know that there is anything listening.
Now the Form1
class looks a bit like this:
public partial class Form1
{
public MachineClass machineObj = new MachineClass();
public void Form1_Load()
{
this.machineObj.FruitUpdate1 += v => label1.ImageIndex = v;
this.machineObj.FruitUpdate2 += v => label2.ImageIndex = v;
this.machineObj.FruitUpdate3 += v => label3.ImageIndex = v;
}
public class MachineClass
{
/* definition from above */
}
}
Here the Form1
class creates the instance of MachineClass
and then attaches handlers to each of the fruit update events. This allows the labels to be updated without the MachineClass
being aware of them at all!
Upvotes: 0
Reputation: 5059
One way, off the top of my head, to do this, would be for the parent class to keep reference to the child, and vice versa. So for this class structure:
class ParentClass
{
public ParentClass()
{
this.child = new ChildClass(this);
}
public ChildClass child { get; set; }
class ChildClass
{
public ParentClass Parent { get; set; }
public ChildClass(ParentClass par)
{
this.Parent = parent;
}
}
}
then any time you wanted to access a field in the parent class from the subclass, you could just call .Parent.Whatever. Granted, this forces you to instantiate both at the same time, so I'm not sure if it's that great a way of accomplishing what you intend, nor whether it'll work for your purposes.
Edit: Alternately, you could use ParentClass as a factory of sorts for ChildClass, like so:
class ParentClass
{
public ParentClass() { }
public class ChildClass
{
public ParentClass Parent { get; set; }
public ChildClass(ParentClass par)
{
this.Parent = par;
}
}
public ChildClass GetChild()
{
return new ChildClass(this);
}
}
and you could instantiate an unlimited number of related ChildClasses from any given ParentClass, and calling .Parent from any ChildClass would refer to the ParentClass from which it was created.
I'd like to make a note, though, that in my experience I've found very few uses for inner classes, and I can't think of a single time where the above class designs would have benefited me. Particularly given that your example doesn't really seem like it's doing anything special, it seems like you'd be better off constructing a normal class outside the scope of your Form class and passing data to it as needed, rather than trying to create a convoluted inner class with a parent/child relation.
Upvotes: 1