Reputation: 581
So I've been trying to solve this problem for hours now and I almost give up. There has to be a way to access a normal Label on a Xamarin C# code behind by another thread.
This is what I'm basically doing:
namespace Traktor
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TrackerPage : ContentPage
{
public delegate void TrackedTimeUpdateHandler(double elapsedTime); // Delegate to notify the TrackingPage of how much time elapsed
private TimeTracker tracker;
// Ctor, and other methods etc. are here
// ...
// Initialize the tracker and add handler to it (called in Ctor)
void Initialize()
{
tracker = new TimeTracker();
tracker.TrackedTimeUpdate += new TrackedTimeUpdateHandler(UpdateGUI);
}
// This method is called periodically by the inner thread of 'tracker'
void UpdateGUI(double elapsedTime)
{
// Status label is a label on the page this refers to
statusLabel.Text = String.Format("{0:F2}", elapsedTime);
// Throws exception: "Android.Util.AndroidRuntimeException: 'Only the original thread that created a view hierarchy can touch its views.'"
}
}
}
A seperate thread runs in TimeTracker tracker
which constantly raises an event to notify this TrackerPage about how much time elapsed. Then the UpdateGUI(...)
- method is called. That is only to set the text of the statusLabel to the elapsed time. Everything works like a charm. But I can not access the statusLabel.Text
by another thread other than the UI- Thread itself.
I tried so much already and its annoying how nothing works because mostly something is missing or other things dont work out. For example, the statusLabel is not a Class that implements ISynchronizeInvoke
, or I cant use the System.Windows.Forms.Control
- Namespace. I dont know why.
So my question is:
Is there a way to access the label (part of the UI on my ContentPage
) and modify it from another thread (or in any way so that the elapsedTime
can be displayed periodically)? I cant invokes and async doesnt seem to fit here. I really dont know how to get around this problem. Or maybe is there a Xamarin native way to invoke on the UI- thread?
What I've tried so far:
-> I cant use the System.Windows.Forms.Control
- Namespace. I dont know why. Maybe because Xamarin doesnt want me to. So System.Windows.Forms.Control.Invoke
and such are not accessible to me.
Upvotes: 1
Views: 901
Reputation: 89204
Essentials contains a helper class to force your code to execute on the main UI thread
MainThread.BeginInvokeOnMainThread(() =>
{
// Code to run on the main thread
});
Upvotes: 2