After redesigning my application somewhat to incorporate a more flexible design, i'm running into some troubles with accessing a method located on the MAINFORM, from another class which runs from within a thread. below are some code snippets to show what i'm trying to do:
MAIN FORM:
public void setAlarmColour(byte[] result, int buttonNumber)
{
if (result != null)
{
this.Invoke((MethodInvoker)delegate
{
//txtOutput1.Text = (result[4] == 0x00 ? "HIGH" : "LOW"); // runs on UI thread
if (result[4] == 0x00)
{
this.Controls["btn" + buttonNumber].BackColor = Color.Green;
}
else
{
this.Controls["btn" + buttonNumber].BackColor = Color.Red;
}
});
}
}
CLASS A:
public void connect(IDeviceInterface device)
{
//send data
byte[] bData = new byte[71];
bData[0] = 240;
bData[1] = 240;
bData[2] = 0;
bData[3] = 1;
bData[68] = 240;
bData[69] = 240;
bData[70] = this.CalculateCheckSum(bData);
try
{
byte[] result = this.SendCommandResult(device.deviceIPAddress, device.devicePort, bData, 72);
//send byte + buttonNumber to setAlarmColour on main thread here.
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
now, to answer a few questions you might be thinking to ask, why do i not want to do some of the things explained in the title.
is there a way i could do this by using delegates / events or such? i've tried reading about doing this but some of it seems confusing and i'm not sure what's going where. Also, like i said, i'm open to new ideas so if you can show me a way of using the options i ruled out in an efficient way then i'm open minded.
Does anyone have any idea how i can access this method in the main form from class A? ps if anyone needs additional information, simply ask.
edit 1: with ideas from jon skeet, i've decided to try and implement events to handle this problem. i'm running into some problems though...
the only time my form knows about the class is when it dynamically creates them based on how many entries / instances of class A i'm creating. in my class A, i have created:
public event EventHandler setAlarmColour = delegate { };
then i fire the event in the same class as such:
this.setAlarmColour(this, new EventArgs());
and subscribe to the event during the dynamic creation of the class, as such:
bfdevice.setAlarmColourDelegate += new EventHandler(setAlarmColour);
where bfdevice = class A and setAlarmColourDelegate is the event handler, and setAlarmColour is my method in mainform i'm trying to access, but i need to pass parameters through to
EventHandler(setAlarmColour)
namely "byte[]result, int buttonNumber" as currently i'm getting "No overload for "setAlarmColour" matches delegate "System.EventHandler" any ideas?
the problem here is that the parameters i need to send to setAlarmColour are only known in class A, which isn't where i'm subscribing to the event. therefore i cannot do setAlarmColour(result, buttonNumber) as mainform has no reference to these.
It sounds like ClassA
could expose a CommandReceived
event. The form would then subscribe to that event for each instance of ClassA
. This is really passing a reference to ClassA
, within the delegate event handler, but it's all hidden.
Fundamentally, each instance of ClassA
has to get back to the instance of the form somehow . I would strongly advise you not to do this via a static variable, which would introduce tight coupling and reduce testability.
If you don't like the event idea, you'll have to pass the reference to ClassA
some other way - eg in the constructor. In this case you'd probably introduce an interface between the two - ClassA
's constructor would have a parameter of the interface type, and your form would implement the interface. That would loosen the coupling between the two.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.