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
相关产品推荐
相关产品推荐

