You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 18:22:18