Blub
Blub

Reputation: 581

Accessing UI component and overwrite it by another thread in Xamarin

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

Answers (1)

Jason
Jason

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

Related Questions