コールバックについて質問があります。デリゲートイベントコールバックのリーダーであるかどうかを知るには?
私は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にグラフを描画するには、これらの値が必要です。
ご協力いただきありがとうございます。
Form1' 'で' WorkingStation'インスタンスの 'SetValueINValCallback'イベントが発生したときには、' Form1'から 'Form2'に' label1.Text'を更新しようとしていますか? – raidensan
イベントの再購読を解除するには、フォームのDisposedイベントを使用する必要があります。 –
Raidensan:私は自分のクラスからform2のlabel1.textを直接更新しようとしています。しかし、私はFrom1を通ってfrom2を導入し、代理人を定義する必要があります。 – Jablonovo