Xamarin Xaml принудительно обновляет элементы интерфейса - PullRequest
1 голос
/ 06 апреля 2019

Пост был переписан, чтобы лучше соответствовать текущей проблеме.

У меня есть кнопка x:Name="selectVesselButton". При нажатии кнопки он пытается установить соединение с сервером, на что уходит секунда или две. Первоначально я хотел, чтобы кнопка была серой, когда она загружала и десериализировала файл json из соединения.

Мой старый код (перед асинхронной попыткой обновления кнопки):

// disabling the button to prevent spam clicking.
string buttonText = selectVesselButton.Text;
selectVesselButton.IsEnabled = false;
selectVesselButton.Text = "loading...";

// retrieve data for speed page.
RetrieveData();
// redirect to next info block if build was successfull.
FocusSpeedblock();

// enabling the button again.
selectVesselButton.Text = buttonText;
selectVesselButton.IsEnabled = true;

Проблема с этим кодом заключалась в том, что визуальные элементы кнопок не обновлялись до тех пор, пока не был завершен RetrieveData (), что полностью противоречило цели этого. Это произошло потому, что код для обновления интерфейса и код для загрузки и десериализации объекта находились в одном потоке.

Однако, следуя совету Ивана, я произвел загрузку и десериализацию Async, что устранило эту проблему (больше похоже на ее перемещение).

Это работает довольно хорошо, но у меня все еще есть проблемы с автоматическим обновлением интерфейса. У меня есть несколько меток, которые необходимо обновить на основе вывода файла JSON. Значение меток обновляется в фоновом режиме, но обновляется только визуально, когда я взаимодействую с метками (т.е. прокручиваю вид прокрутки, на котором они находятся). Проверьте правку 3 для более подробной информации.

РЕДАКТИРОВАТЬ 3:

Когда второй поток закончен, он должен вызвать UpdateSpeedLabels () и обновить некоторые метки. Тем не менее, они обновляются в codebehind, без немедленного обновления интерфейса. Они обновляются только если я взаимодействую с этими ярлыками.

1 Ответ

2 голосов
/ 06 апреля 2019

Предпочтительный способ сделать это на Xamarin - привязка данных. Поскольку вы отказались от этого, это все еще возможно.

Вам нужно убедиться, что ваша длинная задача не выполняется в потоке пользовательского интерфейса, поскольку она блокирует ее и предотвращает ее обновления. Вы делаете это с помощью Task.Run(() => { your task code });. Однако вы не можете обновить свой пользовательский интерфейс внутри Task.Run, так как он не работает в потоке пользовательского интерфейса и может привести к сбою приложения, поэтому вам нужно использовать Device.BeginInvokeOnMainThread(() => { your UI code }); в Task.Run для этой части.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...