You need to enable JavaScript to run this app. 如何在Xamarin.Forms中实现折扣百分比与金额文本框的双向联动计算
优惠活动
大模型
产品
解决方案
定价
更多

如何在Xamarin.Forms中实现折扣百分比与金额文本框的双向联动计算

问题根源

当前的死循环问题来自两个设计缺陷:

  • 计算逻辑中同时对Discount和Percent两个变量赋值,修改任意一个变量都会触发另一个的变更事件,循环调用计算逻辑
  • TextChanged事件每输入一个字符就触发,用户还未完成输入就会触发计算,容易出现异常值

修复方案

第一步:修改C#逻辑,区分计算触发来源

给计算方法增加触发来源标识,只对非用户手动修改的字段进行赋值,同时增加防重入标记和除0保护:

PercentChangedCommand = new Xamarin.Forms.Command(() => CalculateData(isPercentChanged: true));
DiscountChangedCommand = new Xamarin.Forms.Command(() => CalculateData(isPercentChanged: false));

// 防重入标记,避免极端情况递归调用
private bool _isCalculating = false;
private void CalculateData(bool isPercentChanged)
{
    if (_isCalculating) return;
    _isCalculating = true;
    try
    {
        SubTotal = amount + Price1 + Price2;
        // 增加小计为0的保护,避免除以0报错
        if (SubTotal <= 0)
        {
            Discount = 0;
            Percent = 0;
        }
        else
        {
            if (isPercentChanged)
            {
                // 用户修改了百分比,仅计算折扣金额
                Discount = SubTotal * (Percent / 100);
            }
            else
            {
                // 用户修改了折扣金额,仅计算百分比,保留0位小数匹配XAML格式
                Percent = Math.Round(Discount / SubTotal * 100, 0);
            }
        }
        GST = SubTotal * 0.07;
        TotalAmount = SubTotal - Discount + GST;
    }
    finally
    {
        _isCalculating = false;
    }
}

第二步(可选,优化输入体验):修改XAML触发时机

如果不需要每输入一个字符就实时计算,可以把触发事件从TextChanged改为Unfocused,等用户完成输入离开输入框时再计算,避免输入过程中数值被改写:

<Grid Grid.Row="4" ColumnDefinitions="0.7*,1*">
    <Frame Grid.Column="0" Style="{StaticResource FrameStyleBlack2}">
        <OnPlatform x:TypeArguments="View">
            <OnPlatform.Android>
                <customstyle:EntryBorderless
                    Keyboard="Numeric"
                    Style="{StaticResource EntryStyle2}"
                    Text="{Binding Percent, StringFormat='{0:F0}'}">
                    <customstyle:EntryBorderless.Behaviors>
                        <xct:EventToCommandBehavior Command="{Binding PercentChangedCommand}" EventName="Unfocused"/>
                    </customstyle:EntryBorderless.Behaviors>
                </customstyle:EntryBorderless>
            </OnPlatform.Android>
        </OnPlatform>
    </Frame>
    <Frame Grid.Column="1" Style="{StaticResource FrameStyleBlack2}">
        <OnPlatform x:TypeArguments="View">
            <OnPlatform.Android>
                <customstyle:EntryBorderless
                    Keyboard="Numeric"
                    Style="{StaticResource EntryStyle2}"
                    Text="{Binding Discount, StringFormat='{0:F2}'}">
                    <customstyle:EntryBorderless.Behaviors>
                        <xct:EventToCommandBehavior Command="{Binding DiscountChangedCommand}" EventName="Unfocused"/>
                    </customstyle:EntryBorderless.Behaviors>
                </customstyle:EntryBorderless>
            </OnPlatform.Android>
        </OnPlatform>
    </Frame>
</Grid>

说明

如果需要实时计算,无需修改XAML的触发事件,仅修改C#逻辑即可解决死循环问题。

内容的提问来源于stack exchange,提问作者Kai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 04:15:02