What I want to accomplish:
When a user presses the back button on shell when in a particular content page, an api request is made to update the listview. OR update the ListView with fluff until the next API request.
What I've tried:
1) PopAsync the form so that users cannot return to the form once completed (to prevent multiple accidental api post requests). Goes to review page. If back button is tapped, the OnAppearing method of the Content page that contains the list does an API request to update the Observable Collection of list items.
This works only when navigating from one Shell Flyout item to another, it does not work when navigating between Content Pages of a given Shell Flyout Item.
2) Using OnDisappearing of the review page sends a Message Center message to the Main Content page to update the list view.
Never works.
3) When Post request is made on the form going directly to the Shell.Current.GoToAsync("///MainContent");
This simply returns me to the outdated version of the observable collection page.
So, in code this looks like:
Shell Item
<FlyoutItem Route="LoggedIn" Title="Calendars"> <FlyoutItem.Icon> <FontImageSource FontFamily="{StaticResource FontAwesomeRegular}" Glyph="{x:Static fontawesome:FontAwesomeIcons.CalendarAlt}" Color="DarkSeaGreen" Size="24"> </FontImageSource> </FlyoutItem.Icon> <ShellSection> <ShellContent Style="{StaticResource MyShell}" ContentTemplate="{DataTemplate mobile:CalendarListPage}" /> </ShellSection> </FlyoutItem>
Main Page
public partial class CalendarListPage : ContentPage { public CalendarListPage() { InitializeComponent(); BindingContext = new CalendarListViewModel(this); BackgroundColor = Color.FromHex("#ededed"); } protected override void OnAppearing() { base.OnAppearing(); BindingContext = new CalendarListViewModel(this); } // Irrelevant code...
Relevant MainPageViewModel Code
public CalendarListViewModel(Page page) { _page = page; CalendarList = new ObservableCollection<CalendarListModelItem>(); MessagingCenter.Subscribe<CalendarListModelItem>(this, "AddNew", (item) => { CalendarList.Add(item); }); AddCalendarListItems(); } private void AddCalendarListItems() { // Api response of list of CalendarListModelItems try { var response = _ApiService.GetCalendarList(); foreach (var item in response) { CalendarList.Add(item); } } catch (Exception e) { // throw error } }
CreateNewPage only contains form and binds to view model
CreateNewCalendarViewModel
private async Task CreateAsync() { var response = await _apiService.CreateCalendar(CreateCalendarModel); if (!string.IsNullOrWhiteSpace(response)) { await _page.Navigation.PushAsync(new PublicCalendarPage(response)); _page.Navigation.RemovePage(_page); } else { // not relevant } }
PublicCalendarPage
protected override void OnDisappearing() { base.OnDisappearing(); var item = new CalendarListModelItem { AccessCode = AccessCode, Name = "Some Name", StartDate = _calendarModel.StartDate, EndDate = _calendarModel.EndDate }; MessagingCenter.Send(item, "AddNew"); }
Any help is appreciated. Thanks!
To update a ListView in ContentPage. Have you tried using an ObservableCollection for the ListView? As soon as you update an item from this ObservableCollection the view will render and delete the listview item for you.
When a user presses the back button on shell when in a particular content page...
Use the Back button behavior in Shell to create a custom button, the may help you.
<ContentPage ...> <Shell.BackButtonBehavior> <BackButtonBehavior Command="{Binding BackCommand}" IconOverride="back.png" /> </Shell.BackButtonBehavior> ... </ContentPage>
Answers
You can use routes to navigate to any page in the application. Routes can be defined on FlyoutItem, Tab, and ShellContent objects.
Check the tutorial about Shell Navigation.
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/shell/navigation
I may have miscommunicated something... the issue isn't with the routing, that works. it's getting a fresh api request to fire prior to the page loading during content page to content page navigation within the shell.
I forgot to mention I'm using VS2019 on XF 4.2
To update a ListView in ContentPage. Have you tried using an ObservableCollection for the ListView? As soon as you update an item from this ObservableCollection the view will render and delete the listview item for you.
Use the Back button behavior in Shell to create a custom button, the may help you.
good call.