【发布时间】:2022-07-13 23:23:35
【问题描述】:
我是 Xamarin 的新手,并且难以将一些获取的对象(在我的例子中为产品)显示为 FlexLayout 中的按钮。
从 API 获取结果并将其解析为对象(产品)工作正常,因为调试表明 ObservableCollection Products 充满了 API 的产品。
我在ProductPage 中放置了一个标签,它显示了apiHelper.Products 列表中的产品数量。此标签会在一段时间后更新并显示正确的产品数量(需要先完成调用和解析)。
由于某种原因,FlexView 内容未更新/“填充”产品。当我启动硬编码的Products 列表时,它在视图初始化时已经包含产品,产品会显示出来,所以FlexView 本身似乎工作正常。
我的 FlexView(放在ProductPage.xaml):
...
# This label is updated when the fetch was succesfull!
<Label Grid.Column="1" Text="{ Binding Products.Count, StringFormat='Fetched products: {0}'}" HorizontalOptions="Fill" BackgroundColor="#FF5959" TextColor="#EEF2FF" HorizontalTextAlignment="Right" VerticalTextAlignment="Center"/>
...
# The products are not shown when the fetch was successfull
<ScrollView Grid.Row="4">
<FlexLayout
BindableLayout.ItemsSource="{Binding Products}"
x:Name="ProductsCollection"
Wrap="Wrap"
Direction="Row"
JustifyContent="Center"
AlignItems="Center"
AlignContent="Start">
<BindableLayout.ItemTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal">
<Button
Text="{Binding button_description}"
WidthRequest="100"
Margin="10"
HorizontalOptions="Center"
VerticalOptions="Center"
TextColor="Black"
BackgroundColor="#EEF2FF"
CommandParameter="{Binding .}"
Clicked="addProductToOrder"
/>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</FlexLayout>
</ScrollView>
ProductPage.xam.cs的构造函数中的相关代码:
public partial class ProductPage : ContentPage
{
public ObservableCollection<Product> Products = { get; }
private ApiHelper apiHelper;
public ProductPage(Order order) {
ApiHelper apiHelper= new ApiHelper();
_ = apiHelper.GetProductsAsync();
this.Products = apiHelper.Products;
BindingContext = this;
}
我的ApiHelper 来获取产品:
private ObservableCollection<Product> _products = new ObservableCollection<Product> { };
public ObservableCollection<Product> Products { get => _products; set { _products = value; OnPropertyChanged("Products"); } }
public async Task<ObservableCollection<Product>> GetProductsAsync() {
Uri baseAddr = new Uri("http://my.app/api/products");
var client = new HttpClient();
HttpResponseMessage response = await client.GetAsync(baseAddr).ConfigureAwait(false);
if (response.IsSuccessStatusCode) {
Products.Add(JsonConvert.DeserializeObject<ObservableCollection<Product>>(await response.Content.ReadAsStringAsync())[0]);
}
return Products;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = "") {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
有趣的是,当我替换该行时:
Products.Add(JsonConvert.DeserializeObject<ObservableCollection<Product>>(await response.Content.ReadAsStringAsync())[0])
ApiHelper 和:Products = JsonConvert.DeserializeObject<ObservableCollection<Product>>(await response.Content.ReadAsStringAsync());,标签也不再更新。可能是因为关注列表的NotifyPropertyChanged没有触发吧?
我的问题:
- 为什么我的
FlexViewAPI 调用成功后没有更新/显示产品? - 怎么可能
Label已更新但FlexLayout不是虽然它们依赖于同一个列表? - 是否需要使用
Products.add或其他数组函数来对数组进行突变,或者像Products = ....这样的东西也可以工作?
【问题讨论】:
标签: c# xamarin xamarin.forms inotifypropertychanged