首页 > 解决方案 > Xamarin Xaml 强制更新界面元素

问题描述

这篇文章已被重写,以更好地适应当前的问题。

我有一个按钮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() 完成之前没有更新,完全违背了这样做的目的。这是因为更新接口的代码和下载和反序列化对象的代码都在同一个线程上。

但是,按照 Ivan 的建议,我进行了异步下载和反序列化,从而解决了这个问题(更像是移动了​​它)。

这工作得很好,但我仍然在自动更新界面时遇到了一些问题。我有一些标签需要根据 json 文件输出进行更新。标签的值在背景上更新,但只有在我与标签交互时才会在视觉上更新(IE 滚动它们所在的滚动视图)。检查编辑3以获取更多详细信息。

编辑 3:

当第二个线程完成后,它应该调用 UpdateSpeedLabels() 并更新一些标签。但是,它们在代码隐藏中更新,而不是立即更新界面。只有当我与这些标签交互时,它们才会更新。

标签: xamlbuttonxamarin.formsinterface

解决方案


在 Xamarin 上执行此操作的首选方法是使用数据绑定。当您选择退出时,它仍然是可能的。

您需要确保您的长任务不会在 UI 线程中运行,因为它会阻止它并阻止其更新。您可以使用Task.Run(() => { your task code });. 但是,您不能在内部更新您的用户界面,Task.Run因为它没有在 UI 线程上运行,并且会导致应用程序崩溃,因此您需要在Device.BeginInvokeOnMainThread(() => { your UI code });内部Task.Run使用该部分。


推荐阅读