2016-10-27 5 views
0

コールバックについて質問があります。デリゲートイベントコールバックのリーダーであるかどうかを知るには?

私は2つの形式(VS2010)を持っています。

「valueIN」の値が変更されたときにイベントを発生させるクラスを作成しました。

フォームが変更されたときに、どのフォームでもValueINを取得できるように、クラスにデリゲートを設定しました。

問題

私はForm2のオブジェクトを作成し、「」valueIN「」を取得することができますので、それにコールバックをリンクします。しかし、form2オブジェクトがインスタンス化されていない場合、実行時はオブジェクトのインスタンス化がないことがわかります。 Form2が私のワーキングステーションに存在することをどのように知っているのですか? この行:SetValueINValCallback(value_received); がすべきは、(Form2のでworkstationlookingで)何かのようになります。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

Form1' 'で' WorkingStation'インスタンスの 'SetValueINValCallback'イベントが発生したときには、' Form1'から 'Form2'に' label1.Text'を更新しようとしていますか? – raidensan

+1

イベントの再購読を解除するには、フォームのDisposedイベントを使用する必要があります。 –

+0

Raidensan:私は自分のクラスからform2のlabel1.textを直接更新しようとしています。しかし、私はFrom1を通ってfrom2を導入し、代理人を定義する必要があります。 – Jablonovo

答えて

0

申し訳ありませんが、私はイベントを起こしていたことが分かりませんでした。 イベントに登録することを代理人に依頼したので、イベントを開催する必要はありません。登録するだけです。 あなたのようなイベントコードと、エラーが理由提起:あなたは

subscriber += new EventHandler... and so on 

などの加入者を持っている必要があります

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

をそして、あなたはT ^ドンあなたが仕事をするデリゲートを持っているので、もうそれを必要とします。あなたの情報を得るためにデリゲートコールバックを購読するだけです。

時間を無駄にして申し訳ありません。

敬具

関連する問題