Xamarin.Forms 无法通过 ViewModel 将 ObservableCollection 绑定到 CollectionList
Posted
技术标签:
【中文标题】Xamarin.Forms 无法通过 ViewModel 将 ObservableCollection 绑定到 CollectionList【英文标题】:Xamarin.Forms unable to bind ObservableCollection to CollectionList via ViewModel 【发布时间】:2021-12-10 15:40:15 【问题描述】:我遇到了这个问题,首先我初始化了我的 ShoppingViewModel(从另一个 ViewModel 中的命令)
使用我的 ShoppingViewModel - 我调用 GetProducts 方法创建产品集合,然后导航到 ShoppingView - 我尝试将这个集合绑定到集合视图。
失败的地方是将一个绑定到另一个。
如果我通过构造函数将集合传递给视图并手动将其附加到 CollectionView 的 ItemSource 属性,它工作正常;
我查阅了几篇关于此的文章,甚至通过了几门 Udemy 课程来解决这个问题,我会尝试将其更改为 listview(从集合视图并使用绑定上下文) - 似乎没有任何工作 - 我不是确定我哪里出错了;
我还尝试查看更改绑定上下文引用是否会有所帮助 - 请帮助我了解我哪里出了问题
购物视图的 XAML 如下
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:FurniturePhoneApp.ViewModel"
x:Class="FurniturePhoneApp.View.ShoppingView"
>
<ContentPage.Resources>
<ResourceDictionary>
<vm:ShoppingViewModel x:Key="vm" />
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content BindingContext="StaticResource vm">
<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.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2"
VerticalItemSpacing="20"
HorizontalItemSpacing="0" />
</CollectionView.ItemsLayout>
<CollectionView.Header>
<StackLayout>
<Label Margin="15,50,15,15"
Text="Explore"
FontAttributes="Bold"
FontSize="Title"
TextColor="#2C2C2C" />
<CollectionView x:Name="CvCategories"
HeightRequest="200"
SelectionMode="Single"
SelectionChanged="CvCategories_SelectionChanged">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal">
<Frame Padding="0"
BackgroundColor="Transparent"
Margin="15,0,15,0"
HasShadow="True">
<StackLayout Orientation="Vertical">
<Frame Padding="0"
CornerRadius="15"
IsClippedToBounds="True"
HeightRequest="150"
WidthRequest="150"
HorizontalOptions="Center">
<Image Aspect="AspectFit"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Source="Binding FullImageUrl"/>
</Frame>
<Label TextColor="#2C2C2C"
HorizontalTextAlignment="Center"
FontSize="Medium"
Text="Binding Name"/>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Label Margin="15,15,15,0"
Text="Trending Products"
TextColor="#2C2C2C"
FontSize="Title"
FontAttributes="Bold" />
</StackLayout>
</CollectionView.Header>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Spacing="0">
<Frame CornerRadius="10"
HasShadow="False"
Margin="15,0,15,0"
Padding="20">
<StackLayout Spacing="5"
Orientation="Vertical">
<Image Aspect="Fill"
HeightRequest="120"
Source="Binding FullImageUrl"/>
<Label TextColor="#2C2C2C"
Text="Binding Name"/>
<Label TextColor="#FA6400"
Text="Binding Price, StringFormat='$0'"/>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentPage.Content>
我的 ShoppingViewModel 在下面
namespace FurniturePhoneApp.ViewModel
public class ShoppingViewModel : INotifyPropertyChanged
public ObservableCollection<ProductByCategory> Products;
public ShoppingViewModel()
GetProducts();
public async void GetProducts()
var items = await ApiService.GetProductByCategory(2);
ObservableCollection<ProductByCategory> Products = new ObservableCollection<ProductByCategory>();
foreach (var item in items)
Products.Add(item);
if (Products != null)
// await Application.Current.MainPage.Navigation.PushAsync(new ShoppingView());
await Application.Current.MainPage.Navigation.PushAsync(new ShoppingView(Products));
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
【问题讨论】:
【参考方案1】:您正在GetProducts
方法中创建一个新的局部变量。您只需评论该行并创建 ObservableCollection
来声明您的变量
public ObservableCollection<ProductByCategory> Products = new ObservableCollection<ProductByCategory>();
public ShoppingViewModel()
GetProducts();
public async void GetProducts()
var items = await ApiService.GetProductByCategory(2);
//ObservableCollection<ProductByCategory> Products = new ObservableCollection<ProductByCategory>();
foreach (var item in items)
Products.Add(item);
if (Products != null)
// await Application.Current.MainPage.Navigation.PushAsync(new ShoppingView());
await Application.Current.MainPage.Navigation.PushAsync(new ShoppingView(Products));
您尝试了很多设置绑定上下文的地方,我通常会这样做(我的个人喜好)
在 XAML 中(没有你所做的资源)
<ContentPage.BindingContext>
<vm:IsNullOrEmptyConverterViewModel />
</ContantPage.BindingContext
或者在页面构造器中
public myNewPage()
BindingContext = new ViewModel();
InitializeComponent();
【讨论】:
以上是关于Xamarin.Forms 无法通过 ViewModel 将 ObservableCollection 绑定到 CollectionList的主要内容,如果未能解决你的问题,请参考以下文章
包“apppxbundle”需要很长时间来处理。无法将更新推送到 Windows 商店 [UWP] [Xamarin.Forms]
无法使用 PCLStorage 或 Xamarin Forms Labs 在 Android 文件系统中创建文件夹/文件