2016-10-27 8 views
0

У меня есть вопрос о обратном вызове.Как узнать, является ли это читателем в обратном вызове события делегата?

У меня есть две формы (VS2010).

Я создал класс, который вызывает событие, когда изменяется значение 'valueIN'.

Я установил делегат в своем классе, чтобы любая форма могла получить ValueIN при его изменении.

Проблема

Я создаю объект Form2 и связать обратный вызов к нему, так что может получить «» valueIN «». но если объект form2 не создается, время выполнения подсказывает мне, что объект не создается. Итак, я хотел бы знать, как узнать, что Form2 существует на моей рабочей станции. Эта линия: SetValueINValCallback(value_received); должен выглядит как-то (В workstationlooking на 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); 
      } 
     } 
    } 
} 

или же она существует другой способ передать событие от класса к нескольким формам?

Мне нужны эти значения, чтобы нарисовать диаграмму в Form2 для примера.

Заранее благодарим за вашу помощь!

+0

Вы пытаетесь обновить 'label1.Text' в' 'Form2' из Form1', когда' SetValueINValCallback' событие 'WorkingStation', например, в' Form1' поднимается? – raidensan

+1

Чтобы отказаться от подписки на событие, вам нужно будет использовать событие Disposed. –

+0

Raidensan: Я пытаюсь обновить label1.text в form2 из моего класса напрямую. Но я должен пройти через From1, чтобы инициировать from2 и определить делегата ... – Jablonovo

ответ

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 

И вы не^т нужно больше, потому что у вас есть делегат, который сделает работу , поэтому вам просто нужно подписаться на обратный вызов делегата, чтобы получить информацию.

Извините за потраченное время.

С наилучшими пожеланиями