Xamarin的.窗体无法通过ViewModel将ObservableCollection绑定到C



我有这个问题,首先我初始化我的ShoppingViewModel(从命令在另一个ViewModel)

使用我的ShoppingViewModel -我调用一个方法GetProducts,它创建了一个产品集合,然后它导航到ShoppingView -在那里我尝试将这个集合绑定到集合视图。

它失败的地方是将一个绑定到另一个。

如果我通过构造函数将集合传递给视图并手动将其附加到CollectionView的ItemSource属性上,则可以正常工作;

我查阅了几篇关于这方面的文章,甚至通过几个Udemy课程来解决这个问题,我试图将其更改为listview(从集合视图和绑定上下文玩)-似乎没有任何工作-我不确定我哪里出错了;

我也试着看看改变绑定上下文引用是否会有所帮助-请帮助我了解我在哪里出错了这个

XAML for Shopping View

<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));
}
}
}

您正在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));
}
}

你尝试了很多地方设置你的绑定上下文,我通常这样做(我的个人偏好)

  1. 在XAML中(没有你所做的资源的事情)

    <ContentPage.BindingContext>
    <vm:IsNullOrEmptyConverterViewModel />
    </ContantPage.BindingContext
    
  2. 或者在Constructor

    页面中
    public myNewPage()
    {
    BindingContext = new ViewModel();
    InitializeComponent();
    }