I've migrated a windows CE 4.20 application to windows CE 5.0. This is not without effort. Some things have to be rewritten. I will explain the steps I took in order to get rid of the error: "Control.Invoke must be used to interact with controls created on a separate thread.".
The application worked fine in windows CE 4.2. What is does is when a transponder is scanned it send an event to the forms. In this event I wanted to set properties of my controls. The code looked like this:
public void HandleISOTagScannedEvent(string isoTag)
{
bool Found = false;
try
{
int Index = 0;
IEnumerator Enumer = cboThings.Items.GetEnumerator();
while(Enumer.MoveNext())
{
Thing ThisThing = new Thing(((DataRowView)Enumer.Current).Row);
if (ThisThing._rfId == isoTag)
{
cboThings.SelectedIndex = Index;
this.SetThing(ThisThing._guid);
Found=true;
break;
}
Index++;
}
if (!Found)
{
FormsManager.ShowMessage("Thing {0} does not exist!", isoTag);
}
}
catch (Exception ex)
{
TraceExceptionForm.Display("TubeSetupForm", "HandleISOTagScannedEvent", ex);
}
}
When I migrated the application to .Net 2.0 and CE 5 and deployed it to the mobile device, everything seem to work. Then I started testing and when I scanned a transponder, the error first occurred. Control.Invoke must be used to interact with controls created on a separate thread. I started to Google around and found the solution on this website by David Kline: http://blogs.msdn.com/davidklinems/archive/2006/03/09/548235.aspx. I had to make a delegate on the form and use this to change the properties. Now the code looks like this:
private delegate void UpdateStatusDelegate(int index, Guid guid);
private void ChangeThing(int index, Guid guid)
{
Cursor.Current = Cursors.WaitCursor;
if (this.InvokeRequired)
{
// we were called on a worker thread
// marshal the call to the user interface thread
this.Invoke(new UpdateStatusDelegate(ChangeThing),
new object[] { index,guid });
return;
}
cboThings.SelectedIndex = index;
this.SetThing(guid);
Cursor.Current = Cursors.Default;
}
public void HandleISOTagScannedEvent(string isoTag)
{
bool Found = false;
try
{
int Index = 0;
IEnumerator Enumer = cboThings.Items.GetEnumerator();
while(Enumer.MoveNext())
{
Thing ThisThing = new Thing(((DataRowView)Enumer.Current).Row);
if (ThisThing._rfId == isoTag)
{
ChangeThing(Index, ThisThing._guid);
Found=true;
break;
}
Index++;
}
if (!Found)
{
FormsManager.ShowMessage("Thing {0} does not exist!", isoTag);
}
}
catch (Exception ex)
{
TraceExceptionForm.Display("SetupForm", "HandleISOTagScannedEvent", ex);
}
}
Problem solved. I hope this can help people with simular problems.
Maybe someone can explain why on wondows CE 4.2 this was not giving any problem and in windows CE 5.0 it is? Or could it have something todo with the compact framework?