You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 13:55:28