Xamarin使用MVVM Helpers时XAML中Label文本属性变更不更新问题
问题原因
- 模型类未实现属性变更通知
你当前的LevelProgress是普通POCO类,仅外层的use属性在整体替换时会触发变更通知,嵌套属性(如use.currentlevel、use.muscularprogress)修改时不会向绑定发送通知。你手动修改XAML绑定表达式再还原会刷新,是因为XAML热重载触发了重新绑定,直接读取了当前最新值,不属于运行时自动变更通知的正常流程。 - 后台线程更新绑定源
你在ViewModel构造函数中用Task.Run开启后台线程执行Loadup方法,在非UI线程更新绑定源属性时,Xamarin.Forms可能不会触发UI刷新。 - 首次启动空值逻辑缺陷
首次启动数据库为空时,GetProgress会返回null,直接访问use.currentlevel会触发空引用异常,你当前的判断逻辑无法覆盖空值场景。
解决方案
第一步:修改LevelProgress模型类
因为你已经引入了MvvmHelpers库,直接让LevelProgress继承ObservableObject,将所有字段改为带变更通知的属性:
using MvvmHelpers; using SQLite; namespace INWORK.Models { public class LevelProgress : ObservableObject { [PrimaryKey, AutoIncrement] public int Id { get; set; } private int _currentlevel; public int currentlevel { get => _currentlevel; set => SetProperty(ref _currentlevel, value); } private bool _pushups; public bool pushups { get => _pushups; set => SetProperty(ref _pushups, value); } private bool _squats; public bool squats { get => _squats; set => SetProperty(ref _squats, value); } private bool _pullups; public bool pullups { get => _pullups; set => SetProperty(ref _pullups, value); } private bool _splitsquats; public bool splitsquats { get => _splitsquats; set => SetProperty(ref _splitsquats, value); } private bool _stepups; public bool stepups { get => _stepups; set => SetProperty(ref _stepups, value); } private bool _tricepdips; public bool tricepdips { get => _tricepdips; set => SetProperty(ref _tricepdips, value); } private bool _legraises; public bool legraises { get => _legraises; set => SetProperty(ref _legraises, value); } private bool _running; public bool running { get => _running; set => SetProperty(ref _running, value); } private bool _intervals; public bool intervals { get => _intervals; set => SetProperty(ref _intervals, value); } private double _muscularprogress; public double muscularprogress { get => _muscularprogress; set => SetProperty(ref _muscularprogress, value); } private double _cardioprogress; public double cardioprogress { get => _cardioprogress; set => SetProperty(ref _cardioprogress, value); } } }
第二步:修正AboutViewModel的加载逻辑
移除后台线程调用,确保在UI线程更新绑定源,同时补全空值判断:
public class AboutViewModel : ViewModelBase { public ICommand GoInfoCommand { get; set; } public AboutViewModel() { Title = "About"; OpenWebCommand = new Command(async () => await Browser.OpenAsync("https://aka.ms/xamarin-quickstart")); // 不要用Task.Run开后台线程,直接异步加载 _ = Loadup(); } private LevelProgress _use; public LevelProgress use { get => _use; set { _use = value; OnPropertyChanged(); } } public async Task Loadup() { var temps = await DataStorage.GetProgress(); // 补全空值判断,覆盖首次启动场景 if (temps == null || temps.currentlevel == 0) { await DataStorage.FirstCreation(); temps = await DataStorage.GetProgress(); } // 切到UI线程赋值,确保触发UI刷新 await Device.InvokeOnMainThreadAsync(() => { use = temps; }); } public ICommand OpenWebCommand { get; } }
修改完成后运行即可看到绑定值会随数据库加载自动刷新。
内容的提问来源于stack exchange,提问作者Emils Legzdins
相关产品推荐
相关产品推荐

