Xamarin.Forms:AppShell页面返回后数据未更新,如何实例化ViewModel构造函数?
解决方案
你的问题核心是ViewModel构造函数仅在页面首次初始化时执行一次,从其他页面返回时页面不会重新创建ViewModel,所以旧数据不会被更新。结合你的场景,推荐以下几种方案:
1. 改用ObservableCollection存储数据
普通List不会触发UI更新通知,必须替换成ObservableCollection<T>,这样集合内容变化时UI会自动刷新:
public class MyViewModel : INotifyPropertyChanged // 确保已实现INotifyPropertyChanged { public User Profile { get; set; } public ObservableCollection<Book> BorrowedBooks { get; set; } = new ObservableCollection<Book>(); public ObservableCollection<Book> Wishlist { get; set; } = new ObservableCollection<Book>(); // 其他属性和INotifyPropertyChanged实现代码... }
2. 抽离数据加载逻辑为独立方法
不要在构造函数里硬编码数据加载,单独写一个可重复调用的方法,方便后续刷新:
private void LoadUserData() { Profile = App.currentUser; User additionalData = JsonConvert.DeserializeObject<User>(Profile.AdditionalData); // 清空现有集合并重新添加数据(避免直接替换集合导致绑定失效) BorrowedBooks.Clear(); foreach (var book in additionalData.BorrowedBooks) { BorrowedBooks.Add(book); } Wishlist.Clear(); foreach (var book in additionalData.Wishlist) { Wishlist.Add(book); } } // 构造函数里初始化时调用一次 public MyViewModel() { LoadUserData(); }
3. 实现自动刷新+手动下拉刷新
自动刷新(返回页面时触发)
在页面的代码后台重写OnAppearing方法,每次页面显示时重新加载数据:
protected override void OnAppearing() { base.OnAppearing(); if (BindingContext is MyViewModel vm) { vm.LoadUserData(); } }
手动下拉刷新(用RefreshView实现)
如果需要用户手动触发刷新,给ViewModel添加刷新命令和状态属性:
public bool IsRefreshing { get; set; } public ICommand RefreshCommand { get; } // 构造函数里初始化命令 public MyViewModel() { RefreshCommand = new Command(() => { IsRefreshing = true; LoadUserData(); IsRefreshing = false; OnPropertyChanged(nameof(IsRefreshing)); // 如果用了MVVM框架(比如Prism)可省略,框架自动处理 }); LoadUserData(); }
然后在XAML里用RefreshView包裹你的CollectionViews:
<RefreshView IsRefreshing="{Binding IsRefreshing}" Command="{Binding RefreshCommand}"> <StackLayout> <CollectionView ItemsSource="{Binding BorrowedBooks}"> <!-- 你的ItemTemplate --> </CollectionView> <CollectionView ItemsSource="{Binding Wishlist}"> <!-- 你的ItemTemplate --> </CollectionView> </StackLayout> </RefreshView>
关键注意点
- 确保ViewModel实现了
INotifyPropertyChanged,否则IsRefreshing、Profile等属性变化时UI不会收到通知 - 不要直接替换
ObservableCollection实例(比如BorrowedBooks = new ObservableCollection<Book>(...)),而是清空后添加新数据,避免绑定失效
内容的提问来源于stack exchange,提问作者spoooooooonman
相关产品推荐
相关产品推荐

