1

I have a page that is registered in the AppShell like this:

 public AppShell()
    {
        InitializeComponent();
        Routing.RegisterRoute(nameof(LesezeichenPage), typeof(LesezeichenPage));
    }

...and the Flyout:

 <FlyoutItem FlyoutDisplayOptions="AsMultipleItems" >
    <ShellContent Title="Lesezeichen" Route="LesezeichenPage" ContentTemplate="{DataTemplate v:LesezeichenPage}">
    </ShellContent>
</FlyoutItem>

Additionally the page can be opened from other pages in the App with an ImageButton:

Shell.Current.GoToAsync("LesezeichenPage");

The problem is with the following approach: I save an Observablecollection to my App's Properties on this page with the following method:

 private void LesezeichenSpeichern(ContentPage contentPage)
    {
        var parentPage = (TabbedPage)contentPage.Parent;
        parentPage.CurrentPage = parentPage.Children[1];

        Bookmarks.Add(new Bookmark { Novene = PickedNovene, Tag = PickedTag, Date =  DateTime.Today.ToString("d/M/yy"), ID = Bookmarks.Count }) ;

        string LesezeichenJson = JsonConvert.SerializeObject(Bookmarks);
        SetProperties("JsonLesezeichen", LesezeichenJson);
    }


    public async static void SetProperties(string property, object value)
    {
        var app = (App)Application.Current;
        app.Properties[property] = value;

        await app.SavePropertiesAsync();
    }

When I open the page the Json will then be deserialised and added to an ObservableCollection in the constructor:

 public LesezeichenViewModel()
    {
        Bookmarks = new ObservableCollection<Bookmark>();
        
        ////Lade Properties wenn in einer vorherigen Session gespeichert
        if (Application.Current.Properties.ContainsKey("JsonLesezeichen"))
        {
            string savedLesezeichen = Application.Current.Properties["JsonLesezeichen"].ToString();
            var InterimBookmarks = JsonConvert.DeserializeObject<ObservableCollection<Bookmark>>(savedLesezeichen);

            foreach (var bookmark in InterimBookmarks)
            {
                Bookmarks.Add(new Bookmark { Novene = bookmark.Novene, Tag = bookmark.Tag, Date = bookmark.Date, IsChecked = false, ID = bookmark.ID });
            }
        }

Unfortunately when I make changes to the ObservableCollection after navigating to the page with Shell.Current.GoToAsync("LesezeichenPage") and then open the page about the FlyoutItem, the constructor won't fire for a second time. Hence the Json cannot be deserialised and the changes won't be visible in the ListView of the page.

I have to make the constructor fire somehow every time when opening the page, if that's possible. Seen a post with UWP about a NavigationCacheMode that can be disabled though ContentPage/TabbedPage don't have these options.

Maybe someone has another idea/approach to solve this?

Rob
  • 57
  • 7
  • 1
    It wouldn't make sense to run a constructor on an already existing object. So the constructor is the wrong place to put this code. What you need is a method that is always run when a page is navigated to. This method is [OnAppearing](https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.page.onappearing?view=xamarin-forms). Move your code to that method. If you need to run slightly different code the *first* time the page appears, put a field `bool _firstTime = true;`, and where appropriate in method do `if (_firstTime) { _firstTime = false; ... do first time stuff ... }` – ToolmakerSteve Jun 08 '21 at 20:53
  • 1
    ... on further thought, `OnAppearing` may happen too late for what you are trying to do. Test on all platforms you support - Page may already have been Measured (layout). You should instead use MVVM, with Bookmarks a property in the VM. In `OnAppearing`, you call an async method (OR Alternative: a method that you run on the UI thread after a short delay) which constructs a new "Bookmarks2", and then does `((MyVM)BindingContext).Bookmarks = Bookmarks2;` to trigger an update to the list. – ToolmakerSteve Jun 08 '21 at 21:17
  • Hi Steve, thx for the hint. I will try OnAppearing with the async method... – Rob Jun 08 '21 at 21:31
  • 1
    Awesome! That did the trick! I've installed NuGet Package BehaviorsPack from Atsushi Nakamura so I could use the Appearing Event of the Page as a Command and bound it to my ViewModel. The bool property is also a very good idea so the App Properties will be only loaded, when they have been changed. Thx u very much Sir! – Rob Jun 09 '21 at 11:46

0 Answers0