Доступ к компоненту пользовательского интерфейса и перезапись его другим потоком в Xamarin - PullRequest
1 голос
/ 26 марта 2020

Итак, я пытался решить эту проблему часами и почти сдался. Должен быть способ получить доступ к обычной метке кода Xamarin C# позади другого потока.

Это то, что я в основном делаю:

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.'"
        }
    }
}

Отдельный поток работает в TimeTracker tracker, который постоянно вызывает событие, чтобы уведомить эту TrackerPage о том, сколько времени прошло. Затем вызывается UpdateGUI(...) - метод. Это только для установки текста statusLabel на истекшее время. Все работает как шарм. Но я не могу получить доступ к statusLabel.Text другим потоком, кроме самого UI-потока.

Я уже так много пробовал, и раздражает, что ничего не работает, потому что в основном чего-то не хватает или другие вещи не работают. Например, statusLabel не является классом, который реализует ISynchronizeInvoke, или я не могу использовать пространство имен System.Windows.Forms.Control. Я не знаю почему.

Итак, мой вопрос: Есть ли способ получить доступ к метке (часть пользовательского интерфейса на моем ContentPage) и изменить ее из другого потока (или в В любом случае, чтобы elapsedTime мог отображаться периодически)? Я не могу вызвать, и asyn c, кажется, не подходит здесь. Я действительно не знаю, как обойти эту проблему. Или, может быть, есть собственный способ Xamarin для вызова в потоке пользовательского интерфейса?


Что я пробовал до сих пор:

-> Я не могу используйте System.Windows.Forms.Control - Пространство имен. Я не знаю почему. Возможно, потому что Ксамарин не хочет, чтобы я Так что System.Windows.Forms.Control.Invoke и такие мне не доступны.

1 Ответ

2 голосов
/ 26 марта 2020

Essentials содержит вспомогательный класс для принудительного выполнения кода в основном потоке пользовательского интерфейса

MainThread.BeginInvokeOnMainThread(() =>
{
    // Code to run on the main thread
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...