Как отличить экраны автозагрузки в Xamarin Forms Shell - PullRequest
0 голосов
/ 27 марта 2020

У меня есть раздел регистрации / входа в систему, а также основное содержимое.

Основное содержимое имеет раздел панели вкладок (вкладки вниз), но я хочу, чтобы эти вкладки отображались только в основном разделе. раздел регистрации / входа не имеет. Во-первых, в моем App.cs мне нужно проверить, существует ли пользователь (учетные данные из безопасного хранилища), и на основе того, что мой API возвращает в качестве ответа, мне нужно показать пользователю правильную страницу (какой-то шаг в регистрации, где он остановился в прошлый раз или если учетные данные в порядке, чтобы перенаправить их в основной сектор с помощью вкладок вниз)

Я настраиваю свой AppShell следующим образом:

    <ShellItem Route="login">
        <ShellContent ContentTemplate="{DataTemplate login:Page1}" />
        <ShellContent ContentTemplate="{DataTemplate login:Page2}" />
    </ShellItem>

    <ShellItem Route="register">

        <ShellContent ContentTemplate="{DataTemplate register:RegisterPage1}" />
        <ShellContent ContentTemplate="{DataTemplate register:RegisterPage2}" />
        <ShellContent ContentTemplate="{DataTemplate register:RegisterPage3}" />
    </ShellItem>


    <TabBar Route="main">
        <Tab Title="Activity" Icon="tab_feed.png">
            <ShellContent ContentTemplate="{DataTemplate postlogin:ActivityPage}" />
        </Tab>
        <Tab Title="Invest" Icon="tab_about.png">
            <ShellContent ContentTemplate="{DataTemplate postlogin:InvestPage}" />
        </Tab>
    </TabBar>

Знаю, что я хочу как-то сообщить код позади AppShell, чтобы основанный на ответе моего API на go на указанную c страницу маршрутизации. Я пробовал что-то вроде:

public AppShell()
        {
            MainThread.BeginInvokeOnMainThread(async () =>
            {
                await Shell.Current.GoToAsync("//register");
            });
            InitializeComponent();
        }

Но у меня исключение нулевой ссылки. Возможно, у вас есть лучшее архитектурное решение?

1 Ответ

0 голосов
/ 27 марта 2020

Я думаю, вы должны рассматривать страницы входа и регистрации отдельно от оболочки. Другими словами, когда приложение запускается, проверьте, нужно ли пользователю войти / зарегистрироваться. Если это так, введите sh страницу входа и / или регистрации в качестве модальной страницы, охватывающей интерфейс Shell. Закончив вход в систему / регистрацию, откройте модальную страницу, и вы окажетесь в своей Оболочке с вкладками.

В качестве альтернативы, вы можете назначить Application.MainPage своей странице входа или регистрации при запуске приложения, а затем, когда завершите, переназначить Application.MainPage на AppShell, например:

MainPage = new LoginPage();
// Authenticated!! - now open the shell
MainPage = new AppShell();

ОБНОВЛЕНИЕ: хотя я не могу думать о том, чтобы убедиться, что страница входа / регистрации находится «в оболочке», тем более что было заявлено, что они не хотят вкладок при отображении страниц регистрации / регистрации, проблема с кодом во вступительном вопросе заключается в том, что они вызывают Shell.Current во время конструктора AppShell. Вероятно, вы можете избежать этой ошибки, добавив await Task.Delay(500), чтобы позволить AppShell завершить построение sh (и вам, вероятно, следует сначала вызвать InitializeComponent), например:

public AppShell()
    {
        InitializeComponent();
        MainThread.BeginInvokeOnMainThread(async () =>
        {
            await Task.Delay(500);
            await Shell.Current.GoToAsync("//register");
        });

    }

Однако это действительно против лучших практики, которые не рекомендуют запускать асин c методы из конструкторов. Вот сообщение в блоге об альтернативе: https://blog.stephencleary.com/2013/01/async-oop-2-constructors.html

например, сделайте что-то вроде:

public sealed class MyClass
{
  private MyData asyncData;
  private MyClass() { ... }

  private async Task<MyClass> InitializeAsync()
  {
    asyncData = await GetDataAsync();
    return this;
  }

  public static Task<MyClass> CreateAsync()
  {
    var ret = new MyClass();
    return ret.InitializeAsync();
  }
}

public static async Task UseMyClassAsync()
{
  MyClass instance = await MyClass.CreateAsync();
  ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...