首次加载页面时,ViewModel 中的 OnNavigatedTo 未触发

OnNavigatedTo in ViewModel isn't firing when page first loads

我正在尝试在 Xamarin.Forms 中实现 Azure Active Directory B2C。如果我只是复制他们的例子,我可以毫无问题地让它工作。但是当我尝试使用 Prism 时,我 运行 遇到了问题。

我获取了位于 XAML:

的代码隐藏中的这段代码
protected override async void OnAppearing ()
{
    base.OnAppearing ();
    App.PCApplication.PlatformParameters = platformParameters;

    try {
        var ar = await App.PCApplication.AcquireTokenSilentAsync(
            AuthenticationInfo.Scopes, string.Empty, AuthenticationInfo.Authority,
            AuthenticationInfo.SignUpSignInpolicy, false);

        AuthenticationInfo.UserAuthentication = ar;
    } catch {               
    }
}

async void OnSignUpSignIn(object sender, EventArgs e)
{
    try {
        var ar = await App.PCApplication.AcquireTokenAsync(
            AuthenticationInfo.Scopes, string.Empty, UiOptions.SelectAccount,
            string.Empty, null, AuthenticationInfo.Authority,
            AuthenticationInfo.SignUpSignInpolicy);

        AuthenticationInfo.UserAuthentication = ar;
    } catch (Exception ex) {
        if (ex != null) {
        }               
    }
}

并将其移动到 ViewModel 的 OnNavigatedTo:

public async void OnNavigatedTo (NavigationParameters parameters)
        {
            if (parameters.ContainsKey ("title"))
                Title = (string)parameters ["title"];

            listen2asmr.App.PCApplication.PlatformParameters = platformParameters;

            try {
                var ar = await listen2asmr.App.PCApplication.AcquireTokenSilentAsync(
                    AuthenticationInfo.Scopes, string.Empty, AuthenticationInfo.Authority,
                    AuthenticationInfo.SignUpSignInpolicy, false);

                AuthenticationInfo.UserAuthentication = ar;
            } catch {

            }
        }

这是在引导程序中:

protected override Xamarin.Forms.Page CreateMainPage ()
        {
            return Container.Resolve<LoginPage> ();
        }

        protected override void RegisterTypes ()
        {
            Container.RegisterTypeForNavigation<LoginPage>();
        }

OnNavigatedTo 似乎从未被调用过。我应该使用其他方法吗,还是我错过了其他方法?我唯一能想到的另一件事是从 ViewModel 构造函数调用 OnNavigatedTo 中的代码,但是 async/await 确实与构造函数一起工作。

我的建议是使用 View 事件作为 ViewModel 触发器

例如:

View.xaml.cs

protected override async void OnAppearing () {
    base.OnAppearing ();
    viewModel.OnAppearing();
}

async void OnSignUpSignIn(object sender, EventArgs e) {
     viewModel.OnSignUpSignIn(sender, e);
} 

ViewModel.cs

protected override async void OnAppearing () {
    App.PCApplication.PlatformParameters = platformParameters;

    try {
        var ar = await App.PCApplication.AcquireTokenSilentAsync(
            AuthenticationInfo.Scopes, string.Empty,
            AuthenticationInfo.Authority,
            AuthenticationInfo.SignUpSignInpolicy, false);

        AuthenticationInfo.UserAuthentication = ar;
    } catch {               
    }
}

async void OnSignUpSignIn(object sender, EventArgs e) {
     try {
         var ar = await App.PCApplication.AcquireTokenAsync(
            AuthenticationInfo.Scopes, string.Empty, 
            UiOptions.SelectAccount,
            string.Empty, null, AuthenticationInfo.Authority,
            AuthenticationInfo.SignUpSignInpolicy);

         AuthenticationInfo.UserAuthentication = ar;
    } catch (Exception ex) {
        if (ex != null) {
        }               
    }
} 

原因:

  1. View 应该只涉及视觉效果,以及您的页面收到的事件。逻辑应该转发给 ViewModel,除非它处理信息的表示(例如,使用切换框进行 2 个选择但使用组合框进行 3 个以上选择的逻辑)。

  2. 几乎相反,ViewModel 应该跟踪 "model state"(例如用户仍然需要输入他们的支付信息)而不是 "view state"(例如用户已导航至付款页面)。

此问题已在 Xamarin.Forms 的最新预览版 Prism 中修复。尝试改用这些包:

https://www.nuget.org/packages/Prism.Forms/6.1.0-pre4 https://www.nuget.org/packages/Prism.Unity.Forms/6.2.0-pre4

引导过程也发生了变化。阅读此内容以获取更多信息: