我正在为产品商店制作客户端应用程序。购物车位于服务器上,数据通过对服务器的请求传输到那里。产品篮子是
ObservableCollection
。该视图还显示 ViewModel
构造函数中生成的总价格。我实现了从 observablecollection 中删除项目的命令,并且还输入了从总金额参数中减去已删除项目的成本的命令。删除的项目将从视图的列表中消失,但显示的数量保持不变。
XAML 代码:
<StackLayout>
<CollectionView ItemsSource="{Binding ProductsInBasket}" VerticalOptions="FillAndExpand" x:Name="clv_basket">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="dataModel:DTOProductAndQuantity">
<Frame Padding="2" Margin="25,10,25,0" HasShadow="False" BorderColor="LightGray" CornerRadius="15">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Frame Grid.Column="0" HasShadow="False" CornerRadius="15" WidthRequest="200" HeightRequest="200" HorizontalOptions="Center">
<Image Grid.Column="0" HeightRequest="200" WidthRequest="200" Margin="0,0,0,0" Source="{Binding product.Photo, Mode=OneWay, Converter={StaticResource ByteToImage}}"/>
</Frame>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Text="{Binding product.NameProduct}" FontSize="19" TextColor="#006064" VerticalOptions="Center" Grid.Row="0"/>
<Label Text="{Binding product.Category}" FontSize="18" TextColor="#006064" VerticalOptions="Center" Grid.Row="1"/>
<Label Text="{Binding product.Cost, StringFormat='cost per piece: {0} rub.'}" FontSize="18" TextColor="#006064" VerticalOptions="Center" Grid.Row="2"/>
</Grid>
<Grid Grid.Column="2">
<StackLayout VerticalOptions="End">
<Label Text="{Binding quantityInBusket}" FontSize="17" HorizontalOptions="Center" TextColor="BlueViolet"/>
<Stepper Maximum="10" HorizontalOptions="Center" Increment="1" Value="{Binding quantityInBusket}"/>
</StackLayout>
<Button VerticalOptions="Start" HorizontalOptions="End" Command="{Binding Path=BindingContext.DeleteProductCommand, Source={x:Reference clv_basket}}" CommandParameter="{Binding}"/>
</Grid>
</Grid>
</Frame>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Frame CornerRadius="2">
<StackLayout>
<Label Text="{Binding Sum, StringFormat='Sum: {0} rub.'}" HorizontalOptions="Center" FontSize="20" TextColor="Black"/>
</StackLayout>
</Frame>
</StackLayout>
视图模型代码:
class BusketViewModel
{
#region Fields
private double sum;
private ObservableCollection<DTOProductAndQuantity> productsInBasket;
private ObservableCollection<DTOProductAndQuantity> productsFromHttp;
HttpClient httpClient = new HttpClient();
private Command<object> deleteProductCommand;
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region Constructor
public BusketViewModel()
{
productsFromHttp = httpClient.GetFromJsonAsync<ObservableCollection<DTOProductAndQuantity>>("http://10.0.2.2:5125/api/Busket").Result;
deleteProductCommand = new Command<object>(DeleteProduct);
ProductsInBasket = new ObservableCollection<DTOProductAndQuantity>(productsFromHttp);
foreach (var i in ProductsInBasket)
Sum += i.product.Cost * i.quantityInBusket;
}
private void DeleteProduct(object obj)
{
Sum -= (obj as DTOProductAndQuantity).product.Cost * (obj as DTOProductAndQuantity).quantityInBusket;
ProductsInBasket.Remove(obj as DTOProductAndQuantity);
}
#endregion
#region Properties
public ObservableCollection<DTOProductAndQuantity> ProductsInBasket
{
get { return productsInBasket; }
set
{
if (productsInBasket != value)
{
productsInBasket = value;
NotifyPropertyChanged();
}
}
}
public Command<object> DeleteProductCommand
{
get { return deleteProductCommand; }
set { deleteProductCommand = value; }
}
public double Sum
{
get { return sum; }
set
{
if (sum != value)
{
sum = value;
NotifyPropertyChanged();
}
}
}
#endregion
protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
重新计算总和最安全
private void DeleteProduct(object obj)
{
var selectedItem_DTOProductAndQuantity = (obj as DTOProductAndQuantity);
if(selectedItem_DTOProductAndQuantity is null)
{
//You can display error message
return;
}
// Sum -= (obj as DTOProductAndQuantity).product.Cost * (obj as DTOProductAndQuantity).quantityInBusket;
ProductsInBasket.Remove(selectedItem_DTOProductAndQuantity);
// Recalculate Sum
Sum = 0;
foreach (var i in ProductsInBasket)
Sum += i.product.Cost * i.quantityInBusket;
}