【发布时间】:2021-12-16 23:10:44
【问题描述】:
我正在尝试在 Xamarin Forms Shell 中创建一个登录流,该流由用户输入其电子邮件地址的第一页和输入密码的第二页组成。 我希望用户能够从密码页面返回并更改输入的电子邮件地址。
这一切都很好,如果最初导航到第一页时,我不通过查询参数设置电子邮件...如果我这样做了,当用户从密码页面返回到电子邮件地址页面时,最初显示传入的电子邮件 - 无论用户可能对其进行了任何更改。
EG:
如果电子邮件页面最初是使用此代码导航到的:
await Shell.Current.GoToAsync($"{nameof(test1)}");
电子邮件地址默认为空白。如果用户将其更改为hello@world.com 并“继续”进入密码页面,然后导航回来,电子邮件地址仍为hello@world.com,如预期的那样。
但是,如果电子邮件页面最初是使用此代码导航到的:
var testEmail = "invalid$$3";
await Shell.Current.GoToAsync($"{nameof(test1)}?EmailAddress={testEmail}");
电子邮件地址按预期显示为invalid$$3。如果用户随后将其更改为 hello@world.com 并“继续”到密码页面,则密码页面按预期在标签中显示 hello@world.com,但如果用户导航返回,电子邮件地址将恢复为电子邮件上的 invalid$$3入口页面(第一页)。
这是我的视图模型:
[QueryProperty(nameof(EmailAddress), nameof(EmailAddress))]
public class LoginViewModel : BaseViewModel
{
string emailAddress;
public string EmailAddress
{
get
{
return emailAddress;
}
set
{
SetProperty(ref emailAddress, Uri.UnescapeDataString(value));
}
}
}
这是第一页(电子邮件条目):
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:The_In_Plaice.ViewModels"
mc:Ignorable="d"
x:Class="The_In_Plaice.Views.test1">
<ContentPage.BindingContext>
<vm:LoginViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout>
<Entry x:Name="txtEmail" Text="{Binding EmailAddress}" Placeholder="email"/>
<Button Clicked="Button_Clicked"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
(后面的代码)
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class test1 : ContentPage
{
public test1()
{
InitializeComponent();
}
private async void Button_Clicked(object sender, EventArgs e)
{
var email = txtEmail.Text;
await Shell.Current.GoToAsync($"{nameof(test2)}?EmailAddress={email}");
}
}
第二页:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:The_In_Plaice.ViewModels"
mc:Ignorable="d"
x:Class="The_In_Plaice.Views.test2">
<ContentPage.BindingContext>
<vm:LoginViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout>
<Label Text="{Binding EmailAddress}"/>
<Entry Text="{Binding Password}" IsPassword="True" Placeholder="password"/>
<Button/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
(后面的代码)
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class test2 : ContentPage
{
public test2()
{
InitializeComponent();
}
}
有什么想法我在这里做错了吗?
【问题讨论】:
-
登录页面
OnAppearing有代码吗? -
不。只需单击按钮(验证电子邮件,如果有效,则导航到密码页面)
-
我没有尝试做你正在做的事情。但是一个想法,如果没有人有更好的答案:覆盖页面的 OnAppearing 和 OnDisappearing。在这些以及 EmailAddress 的设置器上设置断点:登录页面的第二次 OnAppearing 是否在 EmailAddress 设置回(不希望的)初始值之前或之后发生?如果是 AFTER,那么您可以在 OnDisappearing 中缓存,在 OnAppearing 中恢复。为避免弄乱第一次调用,如果您的缓存值为空,请跳过恢复。
-
@ToolmakerSteve 所以,OnAppearing 发生在 viewmodel 更新为原始值之后,所以我实现了你的第一个 hack 想法。这样可行。我不喜欢它大声笑.. 但它肯定让我通过了这个问题。感谢您的想法!
-
很高兴破解成功了!如果有机会,请在下方添加“您的答案”。这将向其他人展示未来如何解决这个问题。 [虽然这是我的想法,但对人们最有帮助的是查看实际工作代码——我不想花时间输入确切的代码!](48 小时后,您可以回来“接受”你自己的答案。)
标签: xamarin.forms xamarin-shell