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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 20:39:04