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

Xamarin.Forms安卓应用始终触发无效提示,输入值未被正确识别

问题描述
  • 目前将Xamarin.Forms应用部署到安卓手机测试(模拟器故障无法修复),之前输入0时应用时而正常时而崩溃,原以为是数学错误并在ViewModel中做了处理,但现在无论输入什么值,都只会触发DisplayInvalidLoginPrompt,不再显示DisplayValidLoginPrompt。
  • 编辑补充:输入0时已不再崩溃,但输入空值时仍会崩溃,且已经在OnSubmit方法的if语句中处理了空值情况,对此感到困惑。

ViewModel代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace Papucometar.ViewModel
{
    public class LoginViewModel : INotifyPropertyChanged
    {
        public Action DisplayInvalidLoginPrompt;
        public Action DisplayValidLoginPrompt;
        public event PropertyChangedEventHandler PropertyChanged = delegate { };
        private string Name;
        public string name
        {
            get { return Name; }
            set
            {
                Name = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Name"));
            }
        }
        int x;
        private string LR;
        public string Lr
        {
            get { return LR; }
            set
            {
                if(Int32.TryParse(value, out x))
                {
                    if(x < 0)
                    {
                        Lr = "1";
                    }
                }
                else
                {
                    LR = value;
                }
                
                PropertyChanged(this, new PropertyChangedEventArgs("LR"));
            }

        }
        private string PI;
        public string Pi
        {
            get { return PI; }
            set
            {
                PI = value;
                PropertyChanged(this, new PropertyChangedEventArgs("PI"));
            }
        }
        int x1;
        private string R;
        public string r
        {
            get { return R; }
            set
            {
                if (Int32.TryParse(value, out x1))
                {
                    if (x1 < 0)
                    {
                        R = "1";
                    }
                }
                else
                {
                    R = value;
                }
                PropertyChanged(this, new PropertyChangedEventArgs("R"));
            }
        }
        public ICommand SubmitCommand { protected set; get; }
        public LoginViewModel()
        {
            SubmitCommand = new Command(OnSubmit);
        }
        public void OnSubmit()
        {
            if (R == null || LR == null || PI == null || Name == null)
            {
                DisplayInvalidLoginPrompt();
            }
            else
            {
                DisplayValidLoginPrompt();
                ClearForm();
            }
        }

            private void ClearForm()
            {
                Name = string.Empty;
                Lr = string.Empty;
                Pi = string.Empty;
                R = string.Empty;
            OnPropertyChanged(nameof(name));
            OnPropertyChanged(nameof(Lr));
            OnPropertyChanged(nameof(Pi));
            OnPropertyChanged(nameof(r));
            }


            protected virtual void OnPropertyChanged(string propertyName)
            {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }

    }

}

后台代码
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Papucometar.ViewModel;
using Xamarin.Essentials;
using System.ComponentModel;
using System.Windows.Input;

namespace Papucometar.View
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class LoginUI : ContentPage
    {
        public LoginUI()
        {
            var vm = new LoginViewModel();
            this.BindingContext = vm;
            if(vm.Lr == "0")
            {
                vm.Lr = "1";
            }
            vm.DisplayInvalidLoginPrompt += () => DisplayAlert("Slamas ga", "Sjebo si ga brate aj opet", "Popravi");
            vm.DisplayValidLoginPrompt += () => DisplayAlert("Nevidjena Papuca", $"{vm.name} je papuca velicine {Math.Abs(int.Parse(vm.Lr)*int.Parse(vm.Pi) / int.Parse(vm.r) )} bacvi na kvadrat", "Ok");
            InitializeComponent();
            name.Completed += (object sender, EventArgs e) =>
            {
                vm.SubmitCommand.Execute(null);
            };

            Lr.Completed += (object sender, EventArgs e) =>
            {
                vm.SubmitCommand.Execute(null);
            };
            Pi.Completed += (object sender, EventArgs e) =>
            {
                vm.SubmitCommand.Execute(null);
            };
            r.Completed += (object sender, EventArgs e) =>
            {
                vm.SubmitCommand.Execute(null);
            };
            
        }

    }
    
}

问题分析与修复

1. 始终触发无效提示的核心问题

ViewModel中Lr和r的属性setter逻辑错误:当输入有效正数时,代码进入Int32.TryParse成功分支,但仅在数值小于0时赋值,正常正数未给LR/R字段赋值,导致这两个字段始终为null,OnSubmit里的R == null || LR == null判断永远为真,一直触发无效提示。

修复Lr属性setter:

public string Lr
{
    get { return LR; }
    set
    {
        if(Int32.TryParse(value, out x))
        {
            // 先赋值,负数再修正为1
            LR = x < 0 ? "1" : value;
        }
        else
        {
            LR = value;
        }
        PropertyChanged(this, new PropertyChangedEventArgs("Lr"));
    }
}

修复r属性setter:

public string r
{
    get { return R; }
    set
    {
        if (Int32.TryParse(value, out x1))
        {
            R = x1 < 0 ? "1" : value;
        }
        else
        {
            R = value;
        }
        PropertyChanged(this, new PropertyChangedEventArgs("r"));
    }
}

2. 空值输入仍崩溃的问题

后台代码的DisplayValidLoginPrompt直接用int.Parse转换值,当输入为空字符串(非null)时会抛出异常,同时OnSubmit仅判断了null,未处理空字符串。

步骤1:完善OnSubmit的空值与有效性判断

public void OnSubmit()
{
    // 同时判断null和空字符串
    if (string.IsNullOrEmpty(R) || string.IsNullOrEmpty(LR) || string.IsNullOrEmpty(PI) || string.IsNullOrEmpty(Name))
    {
        DisplayInvalidLoginPrompt();
        return;
    }

    // 安全转换整数,同时避免除以0
    if(int.TryParse(LR, out int lrVal) && int.TryParse(PI, out int piVal) && int.TryParse(R, out int rVal) && rVal != 0)
    {
        DisplayValidLoginPrompt(lrVal, piVal, rVal);
        ClearForm();
    }
    else
    {
        DisplayInvalidLoginPrompt();
    }
}

步骤2:修改ViewModel的委托定义

// 改为带参数的委托,避免在后台做不安全转换
public Action<int, int, int> DisplayValidLoginPrompt;
public Action DisplayInvalidLoginPrompt;

步骤3:修改后台代码的委托绑定

vm.DisplayValidLoginPrompt += (lr, pi, r) => DisplayAlert("Nevidjena Papuca", $"{vm.name} je papuca velicine {Math.Abs(lr * pi / r)} bacvi na kvadrat", "Ok");

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 11:57:03