【发布时间】:2021-04-06 21:44:17
【问题描述】:
我正在努力为我的应用程序提供愿望清单功能,方法是通过 MVVM 在列表中的每个产品上点击愿望清单图标。一旦被点击,就会调用 API 来更新数据库(从愿望清单表中添加/删除)。根据 api 调用的结果,我将特定产品的相应属性更新为“真”或“假”。属性更新后,我想更改相应产品的图标图像源。我在愿望清单图标上使用触发器来区分非愿望清单和 wiahlist 产品,同时绑定列表本身。
我的代码如下,
型号
public class PublisherProducts
{
public long ProductId { get; set; }
public string ProductName { get; set; }
public string ImageURL { get; set; }
public decimal Price { get; set; }
public bool IsWishlistProduct { get; set; }
}
视图模型
public class OnlineStoreViewModel : BaseViewModel
{
private ObservableCollection<PublisherProducts> publisherProducts;
public Command<long> WishlistTapCommand { get; }
public OnlineStoreViewModel()
{
publisherProducts = new ObservableCollection<PublisherProducts>();
WishlistTapCommand = new Command<long>(OnWishlistSelected);
}
public ObservableCollection<PublisherProducts> PublisherProducts
{
get { return publisherProducts; }
set
{
publisherProducts = value;
OnPropertyChanged();
}
}
public async Task GetProducts(long selectedCategoryId)
{
try
{
...
PublisherProducts = new ObservableCollection<PublisherProducts>(apiresponse.ProductList);
...
}
catch (Exception ex) { ... }
finally { ... }
}
async void OnWishlistSelected(long tappedProductId)
{
if (tappedProductId <= 0)
return;
else
await UpdateWishlist(tappedProductId);
}
public async Task UpdateWishlist(long productId)
{
try
{
var wishlistResponse = // api call
var item = PublisherProducts.Where(p => p.ProductId == productId).FirstOrDefault();
item.IsWishlistProduct = !item.IsWishlistProduct;
PublisherProducts = publisherProducts; *Stuck here to toggle wishlist icon*
await App.Current.MainPage.DisplayAlert("", wishlistResponse.Message, "Ok");
}
catch (Exception ex) { ... }
finally { ... }
}
}
XAML
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" ... >
<ContentPage.Content>
<ScrollView>
<StackLayout Padding="15,0,15,10">
<FlexLayout x:Name="flxLayout" BindableLayout.ItemsSource="{Binding PublisherProducts}" ...>
<BindableLayout.ItemTemplate>
<DataTemplate>
<AbsoluteLayout Margin="6" WidthRequest="150">
<Frame Padding="0" WidthRequest="150" CornerRadius="10" HasShadow="True">
<StackLayout Orientation="Vertical" Padding="10" HorizontalOptions="FillAndExpand">
<Image Source="{Binding ImageURL}" WidthRequest="130" HeightRequest="130" HorizontalOptions="Center"/>
<Label Text="{Binding ProductName}" Style="{StaticResource ProductNameStyle}"></Label>
...
<StackLayout ...>
...
<Frame x:Name="wlistFrame" Padding="0" WidthRequest="30" HeightRequest="30" CornerRadius="10" BorderColor="#02457A">
<StackLayout Orientation="Horizontal" VerticalOptions="Center" HorizontalOptions="Center">
<Image x:Name="wlImage" WidthRequest="13" HeightRequest="12" HorizontalOptions="Center" VerticalOptions="Center" Source="ic_wishlist_open">
<Image.Triggers>
<DataTrigger TargetType="Image" Binding="{Binding IsWishlistProduct}" Value="true">
<Setter Property="Source" Value="ic_wishlist_close" />
</DataTrigger>
</Image.Triggers>
</Image>
</StackLayout>
<Frame.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Source={RelativeSource AncestorType={x:Type local:OnlineStoreViewModel}}, Path=WishlistTapCommand}" CommandParameter="{Binding ProductId}" NumberOfTapsRequired="1" />
</Frame.GestureRecognizers>
</Frame>
</StackLayout>
</StackLayout>
</Frame>
</AbsoluteLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</FlexLayout>
</StackLayout>
</ScrollView>
</ContentPage.Content>
</ContentPage>
当 UpdateWishlist() 中的“IsWishlistProduct”属性值发生更改时,我被困在这个地方以更改愿望列表图标。
【问题讨论】:
-
显示两个图标并根据需要切换它们的 IsVisible 属性可能会更简单
-
@Jason,你的意思是像 IsVisible = {Binding IsWishlistProduct}。我也试过了。当 VM 中“IsWishlistProduct”的值发生变化时,它不会反映在 View 中。
-
如果您希望在模型更改时刷新 UI,您的模型必须实现 INotifyPropertyChanged
-
模型还是视图模型? VM 已经通过 BaseViewModel 继承了它
-
无论哪个类包含
IsWishlistProduct,如果这是您想要触发 UI 更改的属性
标签: xamarin.forms mvvm data-binding