Xamarin Forms: сохранить выбранную вкладку после перезапуска активности

На моей главной странице используется TabbedPage для группировки существующих новостей в разные списки. Вкладки не фиксируются; они создаются на основе операций привязки данных к коллекции, которая повторяется через вызов веб-службы.

Я хотел бы сохранить выбранную вкладку при перезапуске активности, но, похоже, я что-то упускаю. Поскольку нет выбранного свойства вкладки (которое можно установить с помощью привязки данных), я попытался обработать события PageChanged и CurrentPageChangedCommand. Я использую PageChanged, чтобы установить выбранную вкладку на предыдущую выбранную вкладку, а CurrentPageChangedCommand используется для обновления сохраненной выбранной вкладки (я использую Application.Properties, чтобы убедиться, что выбранная вкладка выживает после перезапуска приложения).

К сожалению, события, генерируемые вкладкой, всегда будут устанавливать вкладку 0 в качестве выбранной вкладки! Вот что я вижу (предположим, что мое приложение было убито, белая вкладка 3 была активной):

  1. Когда данные привязаны к свойству TabbedPage.ItemsSource, вкладка автоматически запускает CurrentPageChangedCommand, передавая первую вкладку (вкладка в позиции 0).
  2. Мой код обрабатывает событие и обновляет текущую сохраненную выбранную вкладку, изменяя выбранную вкладку в словаре Properties. Итак, теперь вместо 3 (которое сохранялось, когда мое приложение было убито), у него будет 0.
  3. Затем вкладка активирует PagesChanged
  4. Когда мой код обрабатывает это событие, он попытается обновить выбранную вкладку. Однако при доступе к выбранной вкладке из словаря Properties он получит вкладку по умолчанию (0), а не 3. Это происходит потому, что CurrentPageChangedCommand был запущен до события PagesChanged (шаг 2), полностью переопределяя ранее сохраненный индекс вкладки.

Это поведение по умолчанию также создает проблемы для пользователя, когда пользователь обновляет текущий список (потяните, чтобы обновить), потому что он всегда в конечном итоге видит список вкладок 0.

Итак, какие-либо подсказки о том, как решить эту проблему? Как вы, ребята, решили это?

Спасибо.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
504
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

К сожалению, мне пришлось отказаться от подхода MVVM... В конце концов, мне пришлось прибегнуть к коду и паре флагов, чтобы контролировать, когда следует обрабатывать сгенерированные события табуляции.

Ответ принят как подходящий

Кажется, этого нельзя достичь с помощью MVVM, поскольку CurrentPage не является связываемым свойством, а CurrentPageChanged является событием.

Однако нет необходимости обрабатывать событие PagesChanged. Вы можете записать индекс в измененном событии, например:

private void MyTabbedPage_CurrentPageChanged(object sender, EventArgs e)
{
    Application.Current.Properties["index"] = this.Children.IndexOf(CurrentPage);
    Application.Current.SavePropertiesAsync();
}

Затем вы можете установить текущую страницу своей страницы с вкладками после загрузки всех вкладок:

object index;
Application.Current.Properties.TryGetValue("index", out index);
if (index != null)
{
    CurrentPage = Children[int.Parse(index.ToString())];
}
// Subscribe the event
CurrentPageChanged += MyTabbedPage_CurrentPageChanged;

Я поместил приведенный выше код в конструктор пользовательской страницы с вкладками, и он мог изменить выбранную вкладку в начальный момент.

Обновлять:

Если вы хотите динамически изменять дочерние элементы страницы с вкладками, вы можете определить свойство, чтобы избежать запуска события при изменении дочерних элементов:

bool shouldChangeIndex = true;

private void MyTabbedPage_CurrentPageChanged(object sender, EventArgs e)
{
    if (shouldChangeIndex)
    {
        var index = this.Children.IndexOf(CurrentPage);
        Application.Current.Properties["index"] = index;
        Application.Current.SavePropertiesAsync();
    }            
}

// Simulate the adjusting
shouldChangeIndex = false;
Children.Clear();           
Children.Add(new MainPage());
Children.Add(new SecondPage());
shouldChangeIndex = true;

object index;
Application.Current.Properties.TryGetValue("index", out index);
if (index != null)
{
    CurrentPage = Children[int.Parse(index.ToString())];
}

Проблема в том, что вкладки инициализируются после конструктора и могут обновляться несколько раз после их первого рендеринга... кстати, была еще раздражающая мерцающая штука... так что я заменил код привязки на выжидая модель представления, и теперь я создаю страницы «вручную», чтобы я мог установить выбранную страницу во время построения

Luis Abreu 30.05.2019 12:14

@LuisAbreu Вы можете вызвать приведенный выше код после обновления ваших вкладок. Установите CurrentPage снова каждый раз, когда вы хотите загрузить новые вкладки.

Anonymous 30.05.2019 12:17

Проблема в том, что событие pagechanged запускается после события currentpagechanged (это то, что я видел в своем коде)...

Luis Abreu 30.05.2019 12:18

@LuisAbreu Теперь я знаю твою проблему. Пожалуйста, смотрите мое обновление.

Anonymous 30.05.2019 13:27

Да, это похоже на то, что я сделал (чтобы удалить раздражающее движение, возникающее во время повторной привязки, я обновил код, чтобы установить выбранную страницу во время рендеринга). К сожалению, это означает, что вы не можете использовать привязки + команды, и вам придется прибегнуть к написанию кода в представлении...

Luis Abreu 30.05.2019 14:35

Другие вопросы по теме