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

Xamarin.Forms中ObservableCollection添加数据后视图不更新问题求助

Xamarin.Forms ObservableCollection 视图不更新问题

调试确认数据已成功添加到ObservableCollection,但视图始终无更新,以下是相关代码及场景:

视图模型中的集合定义

private ObservableCollection<Transaction> transactions = new ObservableCollection<Transaction>();
public ObservableCollection<Transaction> Transactions
{
    get { return transactions; }
    set
    {
        transactions = value;
        OnNotifyPropertyChanged();
    }
}

Transaction 实体类

public class Transaction:BaseViewModel
{
    private string name = null;
    private string price = null;
    private double numPrice = 0;
    private string date = null;
    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            OnNotifyPropertyChanged();
            name = value;
        }
    }
    public string Price
    {
        get
        {
            return price;
        }
        set
        {
            OnNotifyPropertyChanged();
            price = value;
        }
    }
    public double NumPrice
    {
        get
        {
            return numPrice;
        }
        set
        {
            OnNotifyPropertyChanged();
            numPrice = value;
        }
    }
    public string DateTime
    {
        get
        {
            return date;
        }
        set
        {
            OnNotifyPropertyChanged();
            date = value;
        }
    }
}

BaseViewModel 基类

public class BaseViewModel : INotifyPropertyChanged
{
    
    protected BaseViewModel()
    {

    }

    #region Events
    public event PropertyChangedEventHandler PropertyChanged;
    #endregion

    protected void OnNotifyPropertyChanged([CallerMemberName] string memberName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(memberName));
        }
    }
}

页面XAML代码

<ScrollView>
    <StackLayout BindableLayout.ItemsSource="{Binding Transactions}">
        <BindableLayout.ItemTemplate>
            <DataTemplate>
                <Frame BackgroundColor="#4D4D4D" CornerRadius="10">
                    <StackLayout Orientation="Horizontal">
                        <StackLayout>
                            <Label Text="{Binding Name}"/>
                            <Label Text="{Binding DateTime}"/>
                        </StackLayout>
                        <Label Text="{Binding Price}" FontSize="20"
                               HorizontalOptions="EndAndExpand" VerticalOptions="CenterAndExpand" Margin="0,0,10,0" />
                    </StackLayout>
                </Frame>
            </DataTemplate>
        </BindableLayout.ItemTemplate>
    </StackLayout>
</ScrollView>

集合更新方法

public void AddTransaction(string name, double price, DateTime dateTime)
{
    Transactions.Add(new Transaction()
    {
        Name = name,
        Price = ($"-{price}€".Replace('.',',')),
        NumPrice = price,
        DateTime = dateTime.ToString("dd.MM.yyyy")
    });
}

问题排查与解决方法

  1. 检查页面BindingContext是否正确设置
    确保页面的BindingContext指向包含Transactions集合的ViewModel实例。可以在页面构造函数中添加:

    BindingContext = new YourViewModel(); // 替换为你的ViewModel类名
    

    或在XAML中声明:

    <ContentPage.BindingContext>
        <local:YourViewModel />
    </ContentPage.BindingContext>
    

    (local需替换为ViewModel所在命名空间的XML命名空间声明)

  2. 修正Transaction类属性通知顺序
    当前属性setter中先触发通知再赋值,会导致视图接收到旧值。需调整为先赋值再触发通知,示例:

    public string Name
    {
        get { return name; }
        set
        {
            if (name != value)
            {
                name = value;
                OnNotifyPropertyChanged();
            }
        }
    }
    

    所有Transaction属性都需做此修正。

  3. 验证BindableLayout兼容性
    BindableLayout从Xamarin.Forms 3.5版本开始支持,若版本过低建议升级。也可临时替换为CollectionView测试:

    <CollectionView ItemsSource="{Binding Transactions}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <!-- 保留原Frame及内部布局 -->
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
    
  4. 确保在UI线程更新集合
    若AddTransaction在后台线程调用,需切换到UI线程执行更新:

    Device.BeginInvokeOnMainThread(() =>
    {
        Transactions.Add(new Transaction()
        {
            Name = name,
            Price = ($"-{price}€".Replace('.',',')),
            NumPrice = price,
            DateTime = dateTime.ToString("dd.MM.yyyy")
        });
    });
    

内容的提问来源于stack exchange,提问作者JohanSolo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 00:55:22