Xamarin中如何从ViewModel获取CustomerInfo数据并绑定到页面展示
存在的核心问题
- ViewModel未实现
INotifyPropertyChanged接口,异步请求结束后给CustomerInfo赋值时,UI无法收到值变更的通知,不会主动刷新。 - 构造函数中直接调用
async void类型的异步方法,时序不可控,页面初始化完成时请求还未返回,初始值为null时UI渲染完成后不会更新。 - 绑定路径错误,
BindingContext为ViewCustomerViewModel实例,要访问Customer类下的属性需要补全层级路径。
修复步骤
- 修改ViewModel实现属性变更通知,调整异步方法返回类型为
Task,避免async void的不可控问题:
using System.ComponentModel; using System.Runtime.CompilerServices; public class ViewCustomerViewModel : INotifyPropertyChanged { private Customer _customerInfo; public Customer CustomerInfo { get => _customerInfo; set { _customerInfo = value; OnPropertyChanged(); } } public static string baseUrl = "https://xxxx/Customers/"; public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public ViewCustomerViewModel() { // 异步加载逻辑不要放在构造函数执行 } public async Task LoadUserInfoAsync() { var url = baseUrl; HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "你的授权token"); string jsonStr = await client.GetStringAsync(url); var res = JsonConvert.DeserializeObject<Customer>(jsonStr); // 此处赋值会自动触发属性变更通知,通知UI更新 CustomerInfo = res; } }
- 调整PageOne后台代码,在页面生命周期的
OnAppearing方法中触发数据加载,保证时序可控:
public PageOne() { InitializeComponent(); BindingContext = new ViewCustomerViewModel(); } protected override async void OnAppearing() { base.OnAppearing(); if (BindingContext is ViewCustomerViewModel vm) { await vm.LoadUserInfoAsync(); } }
- 修正XAML中的绑定路径,补全
CustomerInfo层级,示例如下(假设Customer类存在Name属性):
<ContentPage ...> <ContentPage.Content> <Label Text="{Binding CustomerInfo.Name}" /> </ContentPage.Content> </ContentPage>
如果需要绑定Customer类的其他属性,把Name替换成对应属性名即可。
内容的提问来源于stack exchange,提问作者Chim Di Tru
相关产品推荐
相关产品推荐

