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

Xamarin.Forms 通过ViewModel绑定ObservableCollection到CollectionView失败求助

问题根因排查

你代码里存在4个核心错误导致绑定失效:

  • 绑定目标必须是公共属性,你写的Products是公共字段,XAML绑定引擎无法识别字段
  • GetProducts方法内重新声明了同名的局部Products变量,仅修改了局部变量的值,类的成员变量完全没有被赋值
  • XAML中通过资源字典声明的ShoppingViewModel实例,和你在外部Command里初始化、加载了数据的VM不是同一个对象,页面绑定的是全新的空VM实例
  • 把页面跳转逻辑写在VM内部违反MVVM解耦原则,也导致实例对应关系混乱

修复方案

第一步:修改ShoppingViewModel代码

namespace FurniturePhoneApp.ViewModel
{
    public class ShoppingViewModel : INotifyPropertyChanged
    {
        // 改为私有字段+公共属性,赋值触发属性变更通知
        private ObservableCollection<ProductByCategory> _products;
        public ObservableCollection<ProductByCategory> Products
        {
            get => _products;
            set
            {
                _products = value;
                OnPropertyChanged(nameof(Products));
            }
        }

        public ShoppingViewModel(){}

        // 异步方法改为返回Task,仅负责加载数据不处理跳转
        public async Task LoadProductsAsync(int categoryId = 2)
        {
            var items = await ApiService.GetProductByCategory(categoryId);
            Products = new ObservableCollection<ProductByCategory>(items);
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

第二步:修改调用端的跳转逻辑(你另一个ViewModel的Command内代码)

// 命令执行逻辑调整为:初始化VM→加载数据→给页面绑定上下文赋值→跳转
var shoppingVm = new ShoppingViewModel();
await shoppingVm.LoadProductsAsync(2);
var shoppingView = new ShoppingView
{
    BindingContext = shoppingVm
};
await Application.Current.MainPage.Navigation.PushAsync(shoppingView);

第三步:修改ShoppingView的XAML代码

删除资源字典里硬编码的VM实例声明,绑定上下文直接继承页面级的赋值即可:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
           xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"    
           x:Class="FurniturePhoneApp.View.ShoppingView">
<ContentPage.Content>
    <StackLayout>
        <Label Text="Below is the selection of our products"
            VerticalOptions="CenterAndExpand" 
            HorizontalOptions="CenterAndExpand" />
        <CollectionView  x:Name="CvProducts"
                            SelectionMode="Single"
                            SelectionChanged="CvProducts_SelectionChanged"
                        ItemsSource="{Binding Products}">
            <!-- 剩余布局代码完全保留即可 -->
        </CollectionView>
    </StackLayout>
</ContentPage.Content>
</ContentPage>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 13:06:02