Xamarin Forms Shell 导航返回时用户修改的邮箱输入数据被还原问题
问题根源
- Xamarin Forms Shell 存在默认特性:导航栈中的页面每次回到前台(即从下一级页面返回当前页)时,会自动将该页面初始导航时携带的Query参数重新赋值给对应
QueryProperty,用户修改后的EmailAddress会被初始参数直接覆盖,这是值被还原的核心原因。 - 你在两个页面的XAML中分别实例化
LoginViewModel,两个ViewModel为完全独立的实例,不存在数据共享,虽不是本次问题的直接诱因,但属于不规范写法。
解决方案
方案1:限制QueryProperty仅首次初始化时赋值
修改LoginViewModel,增加初始化标记,仅第一次接收Shell传递的参数时赋值,后续返回页面时不再覆盖用户修改的值:
[QueryProperty(nameof(EmailAddress), nameof(EmailAddress))] public class LoginViewModel : BaseViewModel { private bool _isEmailInitCompleted; private string emailAddress; public string EmailAddress { get => emailAddress; set { // 仅首次接收Shell导航参数时赋值,后续跳过 if (!_isEmailInitCompleted) { SetProperty(ref emailAddress, Uri.UnescapeDataString(value)); _isEmailInitCompleted = true; return; } // 用户手动修改输入框时正常赋值 SetProperty(ref emailAddress, value); } } }
方案2:页面后台接收参数,仅首次加载时赋值(更稳妥)
将参数接收逻辑从ViewModel迁移到页面后台,仅在页面首次加载时给ViewModel赋值,从根源避免重复覆盖的问题:
- 首先移除
LoginViewModel上的[QueryProperty]特性,简化属性定义:
public class LoginViewModel : BaseViewModel { private string emailAddress; public string EmailAddress { get => emailAddress; set => SetProperty(ref emailAddress, value); } }
- 修改test1页面后台代码,接收参数并控制赋值时机,同时补充参数URL编码处理,避免特殊字符导致解析错误:
[QueryProperty(nameof(InitEmail), nameof(InitEmail))] [XamlCompilation(XamlCompilationOptions.Compile)] public partial class test1 : ContentPage { public string InitEmail { get; set; } public test1() { InitializeComponent(); } protected override void OnAppearing() { base.OnAppearing(); // 仅首次加载时赋值初始邮箱 if (!string.IsNullOrEmpty(InitEmail) && BindingContext is LoginViewModel vm && string.IsNullOrEmpty(vm.EmailAddress)) { vm.EmailAddress = Uri.UnescapeDataString(InitEmail); InitEmail = null; } } private async void Button_Clicked(object sender, EventArgs e) { var email = txtEmail.Text; // 跳转前对参数做URL编码,避免特殊字符截断参数 await Shell.Current.GoToAsync($"{nameof(test2)}?EmailAddress={Uri.EscapeDataString(email)}"); } }
可选优化:共享ViewModel实例
如果后续需要两个页面共享登录相关数据(如邮箱、密码),可以不用在XAML中分别实例化ViewModel,改为使用单例模式或者导航时传递同一个ViewModel实例,让两个页面操作同一份数据,无需重复传递参数。
内容的提问来源于stack exchange,提问作者Sk93
相关产品推荐
相关产品推荐

