0

我有一个关于回调的问题。

我有两种形式(VS2010)。

我创建了一个类,当“valueIN”发生变化时会引发一个事件。

我在我的班级中设置了一个委托,以便任何表单在更改时都可以获取 ValueIN。

问题

我创建 Form2 对象并将回调链接到它,以便它能够获取“valueIN”。但如果 form2 对象未实例化,则运行时会告诉我该对象没有实例化。所以我想知道我怎么知道我的WorkingStation中存在Form2。这一行:SetValueINValCallback(value_received); 应该看起来像东西(在工作站中查看 Form2):if(SetValINCallbackFn.exists) SetValueINValCallback(value_received);

表格2

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");
        }
    }
}

工作站

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);
            }
        }
    }
}

还是存在将事件从一个类传递到多个表单的另一种方式?

例如,我需要这些值在 Form2 中绘制图表。

在此先感谢您的帮助!

4

1 回答 1

0

抱歉,因为我没有看到我正在发起活动。如果我做了一个委托是订阅事件,所以我不需要一个引发事件,我只需要订阅。引发错误是因为如果您编写如下事件:

 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);
        }

你需要有一个像这样的订阅者

subscriber += new EventHandler... and so on

而且您不再需要它,因为您有完成这项工作的代表。所以您只需订阅委托回调即可获得您的信息。

很抱歉浪费时间。

此致

于 2016-10-28T07:51:44.037 回答