MVVM架构下如何从ViewModel更新ContentPage中Label的文本值?
问题原因及解决方案
核心问题:属性未触发UI更新通知
你的ownrName是普通自动属性,没有实现属性变更通知机制,当你给它赋值时,UI无法感知到值的变化,因此不会更新显示。同理grpVisible也存在同样的问题,只是当前你未关注到它的UI更新情况。另外,异步操作中使用.Result可能引发线程死锁,需要同步修正。
具体修复步骤
改造
ownrName属性,实现通知
由于你的ViewModel继承了ObservableValidator(该类已实现INotifyPropertyChanged接口),可以通过两种方式实现属性通知:方式一:使用CommunityToolkit.Mvvm的
[ObservableProperty]特性(推荐)将原普通属性替换为带特性的私有字段,框架会自动生成带通知的公开属性:
// 替换原来的public string ownrName { get; set; } [ObservableProperty] private string _ownrName;注意:特性会自动生成首字母大写的公开属性
OwnrName,需同步修改XAML中的绑定:Text="{Binding OwnrName, Mode=TwoWay}"方式二:手动实现属性通知
若想保留原属性名
ownrName,可手动编写属性的get/set并调用SetProperty方法:private string _ownrName; public string ownrName { get => _ownrName; set => SetProperty(ref _ownrName, value); }这种方式无需修改XAML绑定。
同步修复
grpVisible属性
给grpVisible添加通知机制,避免后续UI更新问题:private bool _grpVisible; public bool grpVisible { get => _grpVisible; set => SetProperty(ref _grpVisible, value); }修正异步操作的死锁风险
在SelNewDb方法中,将阻塞式的.Result改为异步等待await:// 替换原来的LakSettings settings = query.FirstOrDefaultAsync().Result; LakSettings settings = await query.FirstOrDefaultAsync();
修复后的关键代码片段
ViewModel中修改后的属性及异步操作部分:
public partial class PgViewModel : ObservableValidator { public SQLiteAsyncConnection ConnStr { get; set; } public ObservableCollection<DbSelect> Dbs { get; set; } = new ObservableCollection<DbSelect>(); public ObservableCollection<Groups> Grps { get; set; } = new ObservableCollection<Groups>(); // 修复后的grpVisible属性 private bool _grpVisible; public bool grpVisible { get => _grpVisible; set => SetProperty(ref _grpVisible, value); } // 修复后的ownrName属性(手动实现方式) private string _ownrName; public string ownrName { get => _ownrName; set => SetProperty(ref _ownrName, value); } LakFuncs laks; public PgViewModel() { laks = new LakFuncs(); } [RelayCommand] public async void SelNewDb() { var dbList = laks.GetDbs(); if (dbList.Count == 0) { await Shell.Current.DisplayAlert("Note:", "No password databases were found.", "OK"); return; } var popup = new SelectDb(dbList); await MopupService.Instance.PushAsync(popup); var rvalue = await popup.PopupDismissedTask; if (rvalue != null) { var Options = new SQLiteConnectionString(rvalue, true); ConnStr = new SQLiteAsyncConnection(Options); var grps = await ConnStr.Table<Groups>().ToListAsync(); Grps.Clear(); foreach (var grp in grps) { Grps.Add(new Groups() { GrpName = grp.GrpName }); } grpVisible = (Grps.Count > 0); } var query = ConnStr.Table<LakSettings>().Where(x => x.Id == 1); // 修复后的异步查询 LakSettings settings = await query.FirstOrDefaultAsync(); ownrName = settings.DbOwner; } }
内容的提问来源于stack exchange,提问作者Bob Gatto
相关产品推荐
相关产品推荐

