ListView在OnAppearing调用WebService时无法刷新的问题求助
解决ListView在PopAsync/DatePicker更新后不刷新的问题
嘿,我仔细看了你的代码和问题描述,发现有两个关键坑导致了ListView不更新的情况,咱们一步步来搞定它:
1. 视图后台的ViewModel实例完全不匹配!
你看你的视图后台代码:
// 这里单独创建了一个ViewModel实例 SuccesViewModel SuccesViewModel = new SuccesViewModel(); public Online_Succes() { InitializeComponent(); // 这里又new了另一个ViewModel,还给BindingContext赋值了 BindingContext = new SuccesViewModel(); } protected override void OnAppearing() { // 你调用的是第一个实例的FillSuccess,但视图绑定的是第二个啊! SuccesViewModel.FillSuccess(); base.OnAppearing(); }
这俩是完全独立的对象!你在OnAppearing里更新的那个ViewModel根本没和视图绑定,所以不管你怎么改SuccesList,视图都不会有反应。
修复方法:把ViewModel实例统一起来:
private SuccesViewModel _succesViewModel; public Online_Succes() { InitializeComponent(); _succesViewModel = new SuccesViewModel(); BindingContext = _succesViewModel; } protected override void OnAppearing() { _succesViewModel.FillSuccess(); base.OnAppearing(); }
2. ViewModel没实现INotifyPropertyChanged,集合替换时视图收不到通知
你的SuccesList看起来是直接赋值的字段,每次FillSuccess都new一个新的ObservableCollection,但视图根本不知道你换了新集合——因为没有属性变更通知。
修复ViewModel:先让ViewModel实现属性变更通知接口,再把SuccesList改成带通知的属性:
public class SuccesViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private ObservableCollection<Succes> _succesList; public ObservableCollection<Succes> SuccesList { get => _succesList; set { _succesList = value; OnPropertyChanged(nameof(SuccesList)); } } private void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public SuccesViewModel() { SuccesList = new ObservableCollection<Succes>(); FillSuccess(); } public void FillSuccess() { SuccesList.Clear(); // 清空现有集合,不用每次new新的 var date = App.Date; BasicHttpBinding binding = CreateBasicHttp(); this.client1 = new BienEtreServiceClient(binding, EndPoint); this.instance = ((IBienEtreService)client1.InnerChannel); // 注意:避免重复订阅事件,先取消再订阅 client1.GetSuccesCompleted -= ClientOnGetSuccesCompleted; client1.GetSuccesCompleted += ClientOnGetSuccesCompleted; client1.GetSuccesAsync(App.UserID, date); } private void ClientOnGetSuccesCompleted(object sender, GetSuccesCompletedEventArgs e) { SuccesList.Clear(); foreach (Succes item in e.Result) { if (item.Date.ToString("yyyy-MM-dd") == App.Date.ToString("yyyy-MM-dd")) { SuccesList.Add(item); } } } }
这里的关键细节:
- 复用现有ObservableCollection,而不是每次创建新的(ObservableCollection本身会触发
CollectionChanged通知视图更新) - 给SuccesList属性加上变更通知,确保万一需要替换集合时视图能感知
- 每次订阅异步回调前先取消订阅,避免多次调用FillSuccess导致回调执行多次
3. DatePicker更新后的处理
对于DatePicker的场景,你只需要在日期选择事件里调用绑定的ViewModel的FillSuccess就行:
private void DatePicker_DateSelected(object sender, DateChangedEventArgs e) { App.Date = e.NewDate; ((SuccesViewModel)BindingContext).FillSuccess(); }
总结
你的核心问题就是ViewModel实例不匹配+缺少属性变更通知,按照上面的步骤改完后,不管是从添加页面PopAsync回来,还是用DatePicker切换日期,ListView都能正常刷新数据了。
内容的提问来源于stack exchange,提问作者Grounch
相关产品推荐
相关产品推荐

