Xamarin Forms ListView ItemsSource绑定后UI不更新问题求助
问题根因
- 你使用的
List<T>不支持集合变更通知,无法在元素新增、删除时主动通知UI更新,Xamarin Forms中需要使用ObservableCollection<T>实现集合变更的自动同步。 - 页面属性未实现
INotifyPropertyChanged接口时,属性重新赋值后无法通知绑定的UI刷新。
修复步骤
步骤1:修改App.xaml.cs的集合类型
将全局集合的类型从List<T>替换为ObservableCollection<T>,该类实现了INotifyCollectionChanged接口,集合元素变更时会自动发送通知给绑定的UI:
// 先引用所需命名空间 using System.Collections.ObjectModel; public partial class App : Application { // 替换IList为ObservableCollection public ObservableCollection<ExpenseEntry> ExpenseEntries { get; set; } public ObservableCollection<string> Categories { get; set; } public App() { InitializeComponent(); // 初始化使用ObservableCollection ExpenseEntries = new ObservableCollection<ExpenseEntry>(); Categories = new ObservableCollection<string>(); Categories.Add("Monthly"); Categories.Add("Vacation"); Categories.Add("Other"); MainPage = new NavigationPage(new MainPage()); } // 其余生命周期代码保持不变 }
步骤2:修改MainPage.xaml.cs的绑定逻辑
构造函数中直接绑定全局集合,无需每次页面显示时重复赋值和重置绑定上下文:
using System.Collections.ObjectModel; public partial class MainPage : ContentPage { public ObservableCollection<ExpenseEntry> ExpenseEntries { get; set; } public MainPage() { InitializeComponent(); // 仅在构造时绑定一次全局集合 ExpenseEntries = (Application.Current as TrackExpensesApp.App).ExpenseEntries; BindingContext = this; } async void OnAddExpenseClicked(object sender, EventArgs e) { await Navigation.PushAsync(new ExpensesEntryPage()); } // 原OnAppearing中的赋值和绑定上下文设置逻辑可以直接删除 protected override void OnAppearing() { // 无需额外操作,ObservableCollection会自动同步全局集合的变更 } async void ExpenseEntriesItemSelected(object sender, SelectedItemChangedEventArgs e) { ExpenseEntry selectedItem = e.SelectedItem as ExpenseEntry; await Navigation.PushAsync(new ExpensePage()); } }
额外注意
如果你后续需要修改ExpenseEntry单个对象的属性(比如修改某条记录的名称、金额)时也能自动更新UI,需要让ExpenseEntry类实现INotifyPropertyChanged接口,示例如下:
using System.ComponentModel; using System.Runtime.CompilerServices; public class ExpenseEntry : INotifyPropertyChanged { private string _name; public string Name { get => _name; set { _name = value; OnPropertyChanged(); } } // DateCreated、Category等其余属性都按照上面的格式实现get/set // ... public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
内容的提问来源于stack exchange,提问作者MrHeadshotzz
相关产品推荐
相关产品推荐

