Xamarin Forms fillig observablecollection via messagingcenter

GelattoGelatto Member ✭✭

Hi Guys,

i`m currently trying to build a xamarin forms application containing 2 views.
An OverviewPage and a ImagePage, both in a navigationpage.
The OverviewPage is like a galerie of images and every image can be opened in a imagepage.
You can also go foreward from imagepage to imagepage.
In the ImagePage there is an additional navigation button which redirects you to the overviewpage.
The galerieitems of the overviewpage are from a property of type observablecollection from my viewmodel bound to a listview.
When you take a picture in the imagepage i send a message via messagingcenter from my imagepagemodel to a method in my overviewpagemodel which is adding my taken picture to my observablecollection.
What i'm currently doing is, everytime you click the additional navigationbutton from the imagepage i create a new instance of OverviewPage which gets the updated overviewpagemodel in the constructor with my updated collection.
As long as i use the build-in navigationbutton to step back from imagepage to overviewpage everything works fine.
But when im using my additional navigationbutton which creates a new instance of overviewpage, my message will be subscriped more then once and the new pictures i take will be added once for every instance of overviewpage created because the message is subscripted that much times.

Do i have to pass my one instance of overviewpage from method to method in order to redirect to this one instace every time or how do i solve my problem?

Thank you very much, Gelatto

Answers

  • GelattoGelatto Member ✭✭

    easier said:

    My Navigationstack:
    MainPage
    OverviewPage
    ImagePage
    ImagePage <-- how do i pop from this page to the existing Overviewpage ?

    Currently i dont pop to the existing page. I push into a new OverviewPage and pass it the refreshed instance of OverviewViewModel.

    Thanks

  • seanydaseanyda GBMember ✭✭✭✭✭

    You can pop the page like this
    await Navigation.PopAsync() or if its a modal page like this await Navigation.PopModalAsync();

    If you want to remove the ImagePage from the stack, so it pops back to the existing "OverviewPage" you can use the RemovePage method.

    You just need to find out the index of the page in the stack.

    Navigation.RemovePage(Navigation.NavigationStack[0]);
    
  • GelattoGelatto Member ✭✭

    await Navigation.PopAsync() / PopModelAsync does not help me because it always pops just the page i am currently in, so in the examplestack above i would be in the first ImagePage.
    Im not sure if RemovePage() will help me either because the amout of ImagePages on the Stack is variable and i would have to remove all pages above my OverviewPage.

    Is there no way like this: Navigation.PushAsync(Navigation.NavigationStack.Select(m => m.GetType() == typeof(OverviewPage))) or another way to navigate into a existing page in the stack?

  • seanydaseanyda GBMember ✭✭✭✭✭

    @Gelatto said:
    await Navigation.PopAsync() / PopModelAsync does not help me because it always pops just the page i am currently in, so in the examplestack above i would be in the first ImagePage.
    Im not sure if RemovePage() will help me either because the amout of ImagePages on the Stack is variable and i would have to remove all pages above my OverviewPage.

    Is there no way like this: Navigation.PushAsync(Navigation.NavigationStack.Select(m => m.GetType() == typeof(OverviewPage))) or another way to navigate into a existing page in the stack?

    Not really, Picture the NavigationStack as a stack of cards. If you were to use your example you would be pushing the OverviewPage on top of the stack, but we will have all the previous pages below it. You need to manage the stack properly. Could you not do a foreach to remove each typeof(ImagePage) from the stack and then PopAsync back to OverviewPage?

  • GelattoGelatto Member ✭✭

    @seanyda said:

    @Gelatto said:
    await Navigation.PopAsync() / PopModelAsync does not help me because it always pops just the page i am currently in, so in the examplestack above i would be in the first ImagePage.
    Im not sure if RemovePage() will help me either because the amout of ImagePages on the Stack is variable and i would have to remove all pages above my OverviewPage.

    Is there no way like this: Navigation.PushAsync(Navigation.NavigationStack.Select(m => m.GetType() == typeof(OverviewPage))) or another way to navigate into a existing page in the stack?

    Not really, Picture the NavigationStack as a stack of cards. If you were to use your example you would be pushing the OverviewPage on top of the stack, but we will have all the previous pages below it. You need to manage the stack properly. Could you not do a foreach to remove each typeof(ImagePage) from the stack and then PopAsync back to OverviewPage?

    i'll give it a try and see if it works, thanks for now :)

  • GelattoGelatto Member ✭✭

    @seanyda somehow i dont get it running properly.

    i'm looping over all pages in the navigationstack and remove those of type ImagePage.
    After removing the first Page i get a Exception because i modify the collection im iterating.
    I created a variable to duplicate the navigationstack so i can iterate over the variable and remove the pages fom the actual navigationstack, but im getting the same exception although im not modifying the collection i iterate through...

  • JGoldbergerJGoldberger USMember, Forum Administrator, Xamarin Team, University Xamurai
    edited August 1

    @Gelatto

    First, I think you may not be using the best tool. More on that later.

    Have you tried using Navigation.PopToRootAsync()? This should pop all of your pages that are on top of your root page. I assume your root page is the overview page.

    As for a better tool, I might suggest that from the overview page, you go to a CarouselPage. A CarouselPage allows swiping forward and back between pages. These can be your image pages. Then when you want to go back you just pop the CarouselPage and you will be back at your overview page.

    Also I am moving this thread to the Xamarin.Forms category.

  • GelattoGelatto Member ✭✭

    @JGoldberger
    Thanks for your answer.

    This is my navigationstack:

    MainPage
    OverviewPage
    VehicleStatePage
    ImagePage
    ImagePage

    Therefore i can't use Navigation.PopToRootAsync().

    Putting the images in a CarouselPage is a good idea for user experience, but when i pop the CarouselPage i'd still be in VehicleStatePage and not in OverviewPage.

    Sorry for the wrong category.

    Gelatto

  • JamesLaveryJamesLavery GBBeta, University ✭✭✭✭✭
    If you want to go from one image to another, then keep the same ImagePage and just change the Image you are currently displaying. Then you won't have the stack management problem.
  • JGoldbergerJGoldberger USMember, Forum Administrator, Xamarin Team, University Xamurai

    @Gelatto said:
    @JGoldberger
    Thanks for your answer.

    This is my navigationstack:

    MainPage
    OverviewPage
    VehicleStatePage
    ImagePage
    ImagePage

    Therefore i can't use Navigation.PopToRootAsync().

    You could use PopToRootAsync and then push a new OverviewPage.

    Putting the images in a CarouselPage is a good idea for user experience, but when i pop the CarouselPage i'd still be in VehicleStatePage and not in OverviewPage.

    This will be an issue not matter what you do. I.e. even if you only have only one ImagePage, popping that page will still leave you at the VehiclesStatePage, same as if you use a CarouselPage or even JamesLavery's good suggestion to just use one ImagePage and change the image (and any data) that that page displays rather than creating a stack of ImagePages.

    What might be another way to go is to push the VehicleStatePage (wrapped in a NavigationPage) as a modal page from the OverviewPage. Then push (non-modal) the ImagePage(s) (or CarouselPage or whatever you decide to use for your image pages). Then when you PopModalAsync() you will be back at the OverviewPage. I've attached a simple sample of this.

Sign In or Register to comment.