如何将CollectionView中Stepper值>0的Addon存入Booking的ObservableCollection
问题描述
我正在开发预订结账页面的Addon添加功能,通过CollectionView展示当前可预订办公场地对应的Addon,每个Addon项包含Stepper控件用于选择数量。需求是在ViewModel的SaveBooking方法中,遍历CollectionView的每个DataTemplate项,当Stepper值大于0时,将该Addon的ImgName、Name、Price及Stepper值(数量)添加到Booking模型的BookedAddons(ObservableCollection
相关代码
BookingInfo.xaml
<CollectionView x:Name="AddonSelection" ItemsSource="{Binding OfficeAddons}" SelectionMode="None"> <CollectionView.EmptyView> <Label Text="No Addons for this Office" TextColor="Gray" HorizontalOptions="Center" VerticalOptions="Center"/> </CollectionView.EmptyView> <CollectionView.ItemTemplate> <DataTemplate> <StackLayout Spacing="10" Orientation="Vertical" Padding="10, 10, 10, 10"> <Image Source="{Binding ImgName}" Aspect="AspectFill" HorizontalOptions="FillAndExpand" /> <StackLayout Orientation="Horizontal"> <Label Text="{Binding Name}" FontSize="Micro"/> <Label Text="{Binding Price}" FontSize="Micro" FontAttributes="Bold"/> </StackLayout> <StackLayout Orientation="Vertical" HorizontalOptions="Center"> <Label x:Name="AddonQuantity" Text="{Binding SelectedQuantity}"/> <Stepper x:Name="AddonQuantityStepper" Minimum="0" Maximum="{Binding Quantity}" Increment="1" Value="{Binding StepperValue}" HorizontalOptions="Center" /> </StackLayout> </StackLayout> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView>
BookingInfoVM.cs
public int SaveBooking() { int addstatus = 0; double numhours = CalculateBookingHourLenght(); bool isActive = IsBookingActive(); Models.Booking newbooking = new Models.Booking(); ... // Addons foreach (Models.Addon OfficeAddon in OfficeAddons) // foreach (StackLayout Data in CollectView:AddonSelection) { // if steppervalue >=1 then ... newbooking.BookedAddons.Add(new Models.Addon { ImgName = OfficeAddon.ImgName, Name = OfficeAddon.Name, Price = OfficeAddon.Price, Quantity = StepperValue //Stuck }); } globalref.TempBooking = newbooking; //addstatus = DBInstance.AddBooking(newbooking); return addstatus; }
Booking.cs
public class Booking { [PrimaryKey, AutoIncrement] public int BID { get; set; } public DateTime Start_datetime { get; set; } //public TimeSpan Start_time { get; set; } public DateTime End_datetime { get; set; } //public TimeSpan End_time { get; set; } public bool isActive { get; set; } public double Total_hours { get; set; } public int NumGuests { get; set; } public string Activity { get; set; } public string TimePeriod { get; set; } //Payment // Foregin key to Booked Office public int OID { get; set; } public int HID { get; set; } public string OName { get; set; } public string OLocation { get; set; } // list of booked selected addons public ObservableCollection<Models.Addon> BookedAddons { get; set; } //public double TotalAddonPrice { get; set; } // Foregin key to Guest User public int UID { get; set; } public string GName { get; set; } public double OfficePrice { get; set; } // Office Hourly * Total_hours public double ServiceFee { get; set; } // set equal to (addon price + office price) * 0.15 public double FinalPrice { get; set; } // equal to office + addon + service }
Addon.cs
public class Addon { [PrimaryKey, AutoIncrement] public int AID { get; set; } [Unique] public string Name { get; set; } public int Quantity { get; set; } public double Price { get; set; } public string ImgName { get; set; } // link to Office by ID public int OID { get; set; } }
解决方案
核心思路是把Stepper的选择值直接绑定到Addon模型的属性上,让UI和数据双向同步,ViewModel不需要操作UI元素,直接从数据集合里就能拿到选中数量。
1. 给Addon模型添加选中数量属性并实现通知
在Addon类里新增SelectedQuantity属性,同时实现INotifyPropertyChanged接口,确保UI变更能同步到数据:
using System.ComponentModel; using System.Runtime.CompilerServices; public class Addon : INotifyPropertyChanged { [PrimaryKey, AutoIncrement] public int AID { get; set; } [Unique] public string Name { get; set; } public int Quantity { get; set; } public double Price { get; set; } public string ImgName { get; set; } public int OID { get; set; } private int _selectedQuantity; public int SelectedQuantity { get => _selectedQuantity; set { if (_selectedQuantity != value) { _selectedQuantity = value; OnPropertyChanged(); } } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
2. 调整XAML中的Stepper绑定
把Stepper的Value绑定到新增的SelectedQuantity,并显式声明双向绑定(确保UI操作能同步到模型):
<StackLayout Orientation="Vertical" HorizontalOptions="Center"> <Label Text="{Binding SelectedQuantity}"/> <Stepper x:Name="AddonQuantityStepper" Minimum="0" Maximum="{Binding Quantity}" Increment="1" Value="{Binding SelectedQuantity, Mode=TwoWay}" HorizontalOptions="Center" /> </StackLayout>
3. 修改SaveBooking方法逻辑
现在可以直接遍历OfficeAddons集合,筛选出选中数量大于0的Addon,添加到BookedAddons中:
public int SaveBooking() { int addstatus = 0; double numhours = CalculateBookingHourLenght(); bool isActive = IsBookingActive(); Models.Booking newbooking = new Models.Booking(); // 初始化集合,避免空引用异常 newbooking.BookedAddons = new ObservableCollection<Models.Addon>(); ... // 处理选中的Addons foreach (Models.Addon officeAddon in OfficeAddons) { if (officeAddon.SelectedQuantity > 0) { newbooking.BookedAddons.Add(new Models.Addon { ImgName = officeAddon.ImgName, Name = officeAddon.Name, Price = officeAddon.Price, Quantity = officeAddon.SelectedQuantity }); } } globalref.TempBooking = newbooking; //addstatus = DBInstance.AddBooking(newbooking); return addstatus; }
4. 初始化时重置选中数量
在ViewModel加载OfficeAddons的时候,记得把每个Addon的SelectedQuantity设为0,避免残留之前的选择状态:
public ObservableCollection<Models.Addon> OfficeAddons { get; set; } public void LoadOfficeAddons(int officeId) { // 从数据库获取对应办公场地的Addons var addons = DBInstance.GetAddonsByOfficeId(officeId); OfficeAddons = new ObservableCollection<Models.Addon>(addons); // 重置选中数量为0 foreach (var addon in OfficeAddons) { addon.SelectedQuantity = 0; } }
内容的提问来源于stack exchange,提问作者prensj
相关产品推荐
相关产品推荐

