I have an winform and an interface callback that continuously sends updates. I want to be able to update a label1.Text from the callback interface. However since the intrface runs on an seperate thread I do not think i can do it directly so I was trying to use a delegate and invoke.
However I am running into an error:
Invoke or BeginInvoke cannot be called on a control until the window handle has been created - at
form1.Invoke(form1.myDelegate, new Object[] { so.getString() });
Here is the full code.
public partial class Form1 : Form
{
MyCallBack callback;
public delegate void UpdateDelegate(string myString);
public UpdateDelegate myDelegate;
public Form1()
{
InitializeComponent();
myDelegate = new UpdateDelegate(UpdateDelegateMethod);
callback = new MyCallBack(this);
CallBackInterfaceClass.SetCallBack(callback);
callback.OnUpdate();
}
public void UpdateDelegateMethod (String str)
{
label1.Text = str;
}
}
class MyTestCallBack : Callback
{
public Form1 form1;
public SomeObject so;
public MyTestCallBack(Form1 form)
{
this.form1 = form;
}
public void OnUpdate(SomeObject someobj)
{
so = someobj;
OnUpdate();
}
public void OnUpdate()
{
form1.Invoke(form1.myDelegate, new Object[] { so.getString() });
}
}
Two questions.
Can anyone explain what I am doing wrong?
Is this actually best method to do this?
Here is the answer based on the reply by bokibeg (see below) with a couple of modifications to make it work:
public partial class Form1 : Form { MyTestCallBack _callback; public Form1() { InitializeComponent(); _callback = new MyTestCallBack(); _callback.MyTestCallBackEvent += callback_MyTestCallBackEvent; _callback.OnUpdate(); } private callback_MyTestCallBackEvent(MyTestCallBackEventArgs e) { if (InvokeRequired) { Invoke(new Action(() => { callback_MyTestCallBackEvent(sender, e); })); return; } label1.Text = e.SomeObject.GetDisplayString(); } class MyTestCallBackEventArgs : EventArgs { public SomeObject SomeObj { get; set; } } class MyTestCallBack : Callback { public event EventHandler<MyTestCallBackEventArgs> MyTestCallBackEvent; private SomeObject _so; protected virtual void OnMyTestCallBackEvent(MyTestCallBackEventArgs e) { if (MyTestCallBackEvent != null) MyTestCallBackEvent(this, e); } public void OnUpdate(SomeObject someobj) { _so = someobj; OnMyTestCallBackEvent(new MyTestCallBackEventArgs { SomeObject = _so }); } }