创建 XAML 个初始页面并导航到选项卡式页面

Create XAML Splash page and navigate to Tabbed page

我几乎已经使用 MVVMLight 并遵循 this article 设置了我的 XF 应用程序。

我现在想介绍一个 XAML 启动页面,通过将其分配给 App.xaml.cs 中的 MainPage 属性 来在启动时加载它。加载后,在初始页面中,我想执行一些异步任务来初始化应用程序,即从 API 等获取初始数据。完成后,我想导航到 MainTabbed 页面。

我还没有写初始化逻辑所以我用Thread.Sleep来模拟这个。

我阅读了很多文章并尝试了一些方法,但我遇到了以下任一问题:

  1. 初始页面已加载,但随后未导航至选项卡式页面。
  2. 启动页面根本不加载并导航到选项卡页面 直接。

This article 是我遇到的最接近的,但我似乎在释放信号量时出错:

05-09 19:22:12.471 I/MonoDroid(14342): System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Threading.SemaphoreFullException: Adding the specified count to the semaphore would cause it to exceed its maximum count.
05-09 19:22:12.471 I/MonoDroid(14342):   at System.Threading.SemaphoreSlim.Release (System.Int32 releaseCount) [0x0004c] in <fcbf47a04b2e4d90beafbae627e1fca4>:0 
05-09 19:22:12.471 I/MonoDroid(14342):   at System.Threading.SemaphoreSlim.Release () [0x00000] in <fcbf47a04b2e4d90beafbae627e1fca4>:0 

感谢关于上述的任何建议或如何使用 xaml 实现启动页面(如果这在概念上有意义的话),因为大多数文章都在本地项目中使用本地实现或图像。

提前致谢。

好的!!所以我弄清楚了导航,也不需要为信号量操心。

以下步骤详细说明了答案:

  1. 在服务class或单独的class中创建long-运行方法如下

    public async Task LongRunning()
    {
        //Write code to download data from an API or something.
    }
    
  2. 创建一个'SplashPage.xaml'文件并将其分配给App.cs中的MainPage属性。这会将 SplashPage 设置为 NavigationStack 中的第一个或根页面。

  3. 如果按照 link 使用 MVVMLight,则:

    一个。创建一个 SplashViewModel.cs 文件。

    b。在 SplashViewModel.cs 中,创建一个名为 Initialize 的私有异步无效方法,其代码如下:

    private async void Initialize()
    {
        //Need to await till the task is done. Very important
        await yourService.LongRunning();
    
        //Only after task is done should it navigate to next page
        NavigationService.NavigateTo(nameof(MainTabbedPage));
    }
    
  4. 导航到 MainTabbedPage 后,MainTabbedPage 将成为导航堆栈中的第 2 个页面。这不应该是第一个页面或根页面应该始终是 MainTabbedPage。此外,不需要再次导航到 SplashPage。为了解决这个问题,将下面的代码放在 MainTabbedPage 的 OnAppearing 事件中。

    protected override void OnAppearing()
    {
        base.OnAppearing();
        var splashPage = Navigation.NavigationStack[0];
        Navigation.RemovePage(splashPage);
    }
    

    这将从导航堆栈中删除 SplashPage 并在导航到任何其他页面之前将 MainTabbedPage 设置为根页面。

  5. 如果不用MVVMLight而是直接在code-behind里面写代码什么的那么步骤3b的代码可以放到code-behind-SplashPage.xaml.cs和Initialize方法可以在构造函数中调用。

我花了很多时间来解决这个问题,所以我希望这在需要时有所帮助。