xaml - 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() 并更新一些标签。但是,它们在代码隐藏中更新,而不是立即更新界面。只有当我与这些标签交互时,它们才会更新。
解决方案
在 Xamarin 上执行此操作的首选方法是使用数据绑定。当您选择退出时,它仍然是可能的。
您需要确保您的长任务不会在 UI 线程中运行,因为它会阻止它并阻止其更新。您可以使用Task.Run(() => { your task code });
. 但是,您不能在内部更新您的用户界面,Task.Run
因为它没有在 UI 线程上运行,并且会导致应用程序崩溃,因此您需要在Device.BeginInvokeOnMainThread(() => { your UI code });
内部Task.Run
使用该部分。
推荐阅读
- vba - 从文档中引用表值后,如何在 Word 中使用 VBA 向主题添加其他文本?
- laravel - 用户注册时保存额外数据
- c# - 使用 PetaPoco 执行 oracle 程序
- flutter - 如何通过多个页面传递文本和图像并在最后一页中预览?
- amazon-athena - MSCK REPAIR TABLE 在增量表上工作异常
- database-design - 零售商店的数据库设计
- java - 通过 Spring 或通过 Maven/Gradle 等构建工具的配置文件有什么区别
- css - 铬问题:焦点可见?(在普通鼠标焦点上显示焦点可见样式)
- javascript - 在使用画布和上下文的 JavaScript 和 CSS 游戏中添加 div
- python - 你知道这个简单的脚本有什么问题吗