0

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.

  • the device class which holds the connect() method runs in a thread. this is because i have multiple of these going on, one for each device i'm trying to monitor, for exampl.
  • i can't instantiate a new form as i need to update the current one, therefore mainForm main = new mainForm() isn't an option
  • using static on my method in the main form causes issues with accessing the form controls it's trying to change in the first place, mainly at the "this.controls[]" part. although if anyonyone has a workaround for this, i'm open to ideas
  • i don't want to pass a reference to the main form IF POSSIBLE as it could get messy handing this around everywhere, and as far as i'm aware it's considered bad practise, especially as projects increase in size. i have done this on an earlier version and i had to pass this reference about 3/4 times before i even got to where i needed to go.

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? p.s. 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.

4

1 に答える 1

3

イベントClassAを公開する可能性があるようです。CommandReceivedフォームは、のインスタンスごとにそのイベントをサブスクライブしますClassA。これは、デリゲートイベントハンドラー内で実際にへの参照を渡しますが、すべて非表示になっています。ClassA

基本的に、の各インスタンスは、何らかのClassA方法でフォームのインスタンスに戻る必要があります。静的変数を介してこれを行わないことを強くお勧めします。これにより、密結合が導入され、妥当性が低下します。

イベントのアイデアが気に入らない場合は、ClassA他の方法(コンストラクターなど)に参照を渡す必要があります。この場合、おそらく2つの間にインターフェースを導入します-ClassAのコンストラクターはインターフェースタイプのパラメーターを持ち、フォームはインターフェースを実装します。それは2つの間の結合を緩めるでしょう。

于 2012-05-29T13:09:36.577 に答える