0

I have a question about callback.

I have two forms(VS2010).

I have made a class that raise an event when the ''valueIN'' change.

I set a delegate in my class so that any Form can get the ValueIN when it changes.

The problem

I create the Form2 object and link a callback to it so it is able to get ''valueIN''. but if the form2 object is not instantiated the run time tells me that there is no instantiation of the object. So I would like to know how do I know that Form2 exists in my WorkingStation. This line: SetValueINValCallback(value_received); should looks like something (In workstationlooking at Form2): if(SetValINCallbackFn.exists) SetValueINValCallback(value_received);

Form2

namespace DelegateTest
{
    using Beckhoff.App.Ads.Core;
    using Beckhoff.App.Ads.Core.Plc;
    using TwinCAT.Ads;
    using System.IO;

    public delegate void DEL_SetValIN(Single value);//test event

    public partial class Form1 : Form
    {
        IBAAdsServer _adsServer;
        WorkingStation WorkStation;
        public Form1()
        {
            InitializeComponent();
            WorkingStation WorkStation = new WorkingStation(_adsServer);
        }

        private void btn_Frm2Open_Click(object sender, EventArgs e)
        {
            Form2 Form2Test = new Form2();
            WorkStation.SetValueINValCallback += new DEL_SetValIN(Form2Test.SetValINCallbackFn);
            Form2Test.Show();
        }
    }
}

namespace DelegateTest
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        public void SetValINCallbackFn(Single Value_received)//refresh valueIN
        {
            label1.Text = Value_received.ToString("F1");
        }
    }
}

WorkStation

namespace DelegateTest
{
    using System;
    using System.Collections.Generic;
    using System.IO;

    using System.Windows.Forms;//msgbox
    using Beckhoff.App.Ads.Core;
    using Beckhoff.App.Ads.Core.Plc;
    using TwinCAT.Ads;

    public class WorkingStation
    {//working station class
        public DEL_SetValIN SetValueINValCallback;

        private static IBAAdsCncClient _cncClient;
        private static IBAAdsPlcClient _plcClient;
        public static List<IBAAdsNotification> _notifications;

      //no need  public event System.EventHandler e_RefreshValueIN;//Input value has changed

        public WorkingStation(IBAAdsServer _adsServer)                  //constructor
        {
            try
            {
                _cncClient = _adsServer.GetAdsClient<IBAAdsCncClient>("CNC");
                _plcClient = _adsServer.GetAdsClient<IBAAdsPlcClient>("PLC");
                _notifications = new List<IBAAdsNotification>();

                var _refreshValueIN = new OnChangeDeviceNotification("GlobalVar.PLC.valueInput", ValINHasChanged);//event handler value
                _plcClient.AddPlcDeviceNotification(_refreshValueIN);
                _notifications.Add(_refreshValueIN);
            }
            catch (Exception Except)
            { MessageBox.Show("Error init object:" + Except.Message); }
        }
        ~WorkingStation()//destructor
        {
            foreach (var notify in _notifications)
            {
                _plcClient.RemovePlcDeviceNotification(notify);
            }
        }
        protected virtual void ValINHasChanged(object sender, BAAdsNotificationItem notification)//get Input value
        {//event method
            Single value_received = 0;
            try
            {
                value_received = _plcClient.ReadSymbol<Single>("valueInput");
                SetValueINValCallback(value_received);
               //no need   EventHandler E_VIChange = e_RefreshValueIN;
               //no need   if (E_VIChange != null)
               //no need       E_VIChange(this, EventArgs.Empty);
            }
            catch (Exception except)
            {
                MessageBox.Show("bad event (valueIN): " + except.Message);
            }
        }
    }
}

or does it exist another way to pass event from a class to multiple Forms?

I need those values to draw a chart in Form2 for an example.

Thanks in advance for your help!

JudgeDreed
  • 143
  • 1
  • 13
  • Are you trying to update `label1.Text` in `Form2` from `Form1` when `SetValueINValCallback` event of `WorkingStation` instance in `Form1` is raised? – raidensan Oct 27 '16 at 13:29
  • 1
    You'll have to use the form's Disposed event to unsubscribe the event again. – Hans Passant Oct 27 '16 at 13:59
  • Raidensan: I'm trying to update label1.text in form2 from my class directly. But I have to pass thru From1 to instanciate the from2 and defining the delegate... – JudgeDreed Oct 27 '16 at 14:46
  • @Jablonovo. Please review your previous questions, it seems you've not accepted an answer ever. Take a look at [tour](https://stackoverflow.com/tour). You can accept your own answers if it solve the problem. – Reza Aghaei Nov 03 '16 at 13:01

1 Answers1

0

Sorry because I didn't see that I was raising an event. If I've made a delegate is to subscribe to the event, so I don't need to had a raising event, I just need to subscribe. The error raised because if you code an event like:

 protected virtual void ValINHasChanged(object sender, BAAdsNotificationItem notification)//get Input value
    {//event method
        {
          EventHandler E_VIChange = e_RefreshValueIN;
          if (E_VIChange != null)
          E_VIChange(this, EventArgs.Empty);
        }

You need to have a subscriber like

subscriber += new EventHandler... and so on

And you don^t need it anymore because you have the delegate that make the job. so you just have to subscribe to the delegate callback to have your info.

Sorry for the wasting of time.

Best regards

JudgeDreed
  • 143
  • 1
  • 13