Xamarin Forms中如何将Picker选择逻辑整合到下单按钮中
Xamarin Forms 非MVVM方案:将Picker选择逻辑整合到下单按钮事件
核心思路
把Picker事件里的即时UI反馈(弹窗、输入框状态)保留,将价格计算、订单生成等逻辑全部移到下单按钮事件中,通过页面级变量存储Picker选中的对象,供下单时直接调用。
第一步:声明页面级变量
在页面类中添加两个变量,存储选中的配送和产品对象:
// 页面级变量,保存Picker选中的配送/产品对象 private DELIVERY _selectedDelivery; private PRODUCT _selectedProduct;
第二步:修改Picker事件(仅保留即时UI操作)
简化Picker的SelectedIndexChanged事件,只处理弹窗提示和输入框状态,把选中对象存入页面变量:
// 配送类型Picker事件 private async void Picker_DeliveryType_SelectedIndexChanged(object sender, EventArgs e) { _selectedDelivery = Picker_DeliveryType.SelectedItem as DELIVERY; if (_selectedDelivery == null) return; var deliveryType = _selectedDelivery.deliveryType; if(deliveryType.Equals("Express", StringComparison.OrdinalIgnoreCase)) { await DisplayAlert("Note", "Estimated Delivery: 2 hours from now", "OK"); entryfieldReservationDate.IsEnabled = false; } else if(deliveryType.Equals("Standard", StringComparison.OrdinalIgnoreCase)) { await DisplayAlert("Note", "Within the day", "OK"); entryfieldReservationDate.IsEnabled = true; } else // Reservation类型 { await DisplayAlert("Note", "Enter Reservation Date", "OK"); entryfieldReservationDate.IsEnabled = true; } } // 产品类型Picker事件 private void Picker_ProductType_SelectedIndexChanged(object sender, EventArgs e) { _selectedProduct = Picker_ProductType.SelectedItem as PRODUCT; if (_selectedProduct == null) return; // 仅更新产品单价Label,总价计算移到下单按钮处理 labelProductPrice.Text = _selectedProduct.productPrice.ToString("C"); // 用货币格式更友好 }
第三步:重写下单按钮事件(整合所有业务逻辑)
在按钮点击事件中完成合法性校验、总价计算、订单保存全流程:
// 下单按钮点击事件 private async void Button_Clicked(object sender, EventArgs e) { // 1. 校验用户输入合法性 if (_selectedDelivery == null) { await DisplayAlert("Error", "Please select a delivery type", "OK"); return; } if (_selectedProduct == null) { await DisplayAlert("Error", "Please select a product type", "OK"); return; } // 预约类型需校验日期是否填写 if (_selectedDelivery.deliveryType.Equals("Reservation", StringComparison.OrdinalIgnoreCase) && string.IsNullOrWhiteSpace(entryfieldReservationDate.Text)) { await DisplayAlert("Error", "Please enter reservation date", "OK"); return; } // 2. 计算订单总金额 decimal totalPrice = _selectedProduct.productPrice; // Express类型添加配送费 if (_selectedDelivery.deliveryType.Equals("Express", StringComparison.OrdinalIgnoreCase)) { totalPrice += _selectedDelivery.deliveryFee; labelDeliveryFee.Text = $"Delivery Fee: {_selectedDelivery.deliveryFee:C}"; } else { labelDeliveryFee.Text = string.Empty; // 非Express清空配送费显示 } // 3. 更新总金额Label labelTotalAmount.Text = $"Total Amount: {totalPrice:C}"; // 4. 构建订单对象(根据你的实体类调整) var waterOrder = new WATER_ORDER(); waterOrder.deliveryType = _selectedDelivery.deliveryType; waterOrder.productType = _selectedProduct.productType; waterOrder.orderTotalAmount = totalPrice; // 预约类型设置日期 if (_selectedDelivery.deliveryType.Equals("Reservation", StringComparison.OrdinalIgnoreCase)) { // 可添加日期格式校验,避免无效输入 if (DateTime.TryParse(entryfieldReservationDate.Text, out DateTime resDate)) { waterOrder.reservationDate = resDate; } else { await DisplayAlert("Error", "Invalid reservation date format", "OK"); return; } } // 5. 保存订单和通知 try { var saveSuccess = await waterorderRepos.Save(waterOrder); var notificationSuccess = await waterorderRepos.SaveCustomerNotification(customerNotification); if (saveSuccess) { await DisplayAlert("Order", "Order successfully placed", "OK"); ClearData(); CloseAllPopup(); } else { await DisplayAlert("Order", "We cannot process your order at the moment.", "OK"); } } catch (Exception ex) { await DisplayAlert("Error", $"Failed to place order: {ex.Message}", "OK"); } }
关键优化点
- 用页面级变量存储选中对象,避免重复类型转换,代码更高效
- 简化多层嵌套判断,总价计算逻辑更清晰
- 增加输入合法性校验和异常捕获,避免崩溃并提升用户体验
- 使用
StringComparison.OrdinalIgnoreCase做字符串比较,避免大小写问题
内容的提问来源于stack exchange,提问作者HelpMeSirPlease
相关产品推荐
相关产品推荐

