Xamarin Forms Ondisappearing() called soon after Onappearing() - xamarin

Ondisappearing() called soon after Onappearing() and onAppearing called right after onDisappearing. I had this issue only on one page. other pages do not have this issue. I found this when I tap on navbar back button, it does not navigate to the previous page, I had to tap twice to navigate back on this particular page..then I found this problem. degraded forms version 4.0 to 3.5 and recreated new page did not solve this issue..help need...
public Cart_Page2 ()
{
InitializeComponent ();
}
protected override void OnAppearing()
{
base.OnAppearing();
var vm = new Cart_page_vm();
vm.Navigation = Navigation;
BindingContext = vm;
}
protected override void OnDisappearing()
{
// MessagingCenter.Send<Cart_page>(this, "cart_page_disappear");
// Navigation.PopAsync();
}

Related

Xamarin Android back button is not working

I had build a Multipager Xamarin App, but after second page Android back button and Navigation back button is not working.
I had tried Shell Backbuttonbehavior , but with this only Top Navigation back button is working
<Shell.BackButtonBehavior>
<BackButtonBehavior Command="{Binding BackCommand}" IconOverride="back.png" />
</Shell.BackButtonBehavior>
I had tried overriding OnAppearing and OnDisappearing to set Current and pervious navigation but that too is not triggering on thrid page
protected override void OnAppearing()
{
base.OnAppearing();
Shell.Current.Navigating += Current_Navigating;
}
protected override void OnDisappearing()
{
base.OnDisappearing();
Shell.Current.Navigating -= Current_Navigating;
}
private async void Current_Navigating(object sender, ShellNavigatingEventArgs e)
{
if (Models.PatientPlannerData.moveNext == false)
{
Shell.Current.Navigating -= Current_Navigating;
await Shell.Current.GoToAsync("..", true);
}
}
For Navigation from one page to another I am using
await Shell.Current.GoToAsync(nameof(Page2));
Everything is working fine till second page, from third page back button is not triggering
For the Android back button, after compilation the Navigation Bar that we call in Xamarin Forms, turns into the Action Bar for Android during runtime.
Set the toolbar after LoadApplication(new App()); in OnCreate of MainActivity.
AndroidX.AppCompat.Widget.Toolbar toolbar
= this.FindViewById<AndroidX.AppCompat.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
And then overrode OnOptionsItemSelected(). When you press the backbutton on navigation bar, this event would be triggered.
public override bool OnOptionsItemSelected(IMenuItem item)
{
}

Xamarin iOS Splash Screen build from Windows Visual Studio

I'm trying to change my app's splash screen into a custom image, I haven't found a solution that solved it for me ... I will be more than happy if someone will be able to solve it.
Thanks
I'm using Xamarin iOS on Windows Visual Studio
You could consider adding a Page to your Forms project as a Splash Page.
like
public App()
{
InitializeComponent();
MainPage = new SplashPage();
}
Then add a delay in SplashPage to jump to MainPage.
public SplashPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
Task.Run(async ()=> {
await Task.Delay(3000);
Device.BeginInvokeOnMainThread(()=> { App.Current.MainPage = new MainPage();});
});
}

Button x:Name="btnBack" not navigating to previous page

I am developing Xamarin Forms application for IOS and Android.I have the list of 3 xamarin form pages say X.xaml, Y.xaml, Z.xaml. Page X.xaml, Y.xaml is having 1 and click on that button it opens the next-next Xamarin form. And last on Z.xaml having 2 buttons btnBack & btnConfirm
<Button x:Name="btnBack"></Button>
<Button x:Name="btnConfirm"></Button>
when I click on that back button I want to navigate it to my previous page, but I don't want it like Navigation Back Button or Hardware Back Button click.
for this I have tried this code this will not work.
Z.xaml.cs
public partial class Z : ContentPage
{
public Z()
{
InitializeComponent();
btnBack.Clicked += btnBack_Clicked;
}
private void btnBack_Clicked(object sender, EventArgs e)
{
var existingPages = Navigation.NavigationStack.ToList();
foreach (var page in existingPages)
{
if(page == this)
Navigation.RemovePage(page);
}
}
}
In this code when I click on Back Button it Navigate me to prevoius page ie Y.xaml once I click on button which is on Y.xaml and open the Z.xaml page it shows me blank.
Y.xaml.cs
public partial class Y: ContentPage
{
public Y()
{
InitializeComponent();
btnZ.Clicked += btnZ_Clicked;
}
void btnZ_Clicked(object sender, System.EventArgs e)
{
Navigation.PushAsync(new Z());
}
}
#Kowalski had the right answer however it is incomplete.
You have to await Navigation.PopAsync() otherwise you may mess up the navigation stack. So always await it. Example:
async void btnBack_Clicked(object sender, EventArgs e)
{
await Navigation.PopAsync();
}
Beside that be aware that there are bugs in Xamarin.Forms related to navigation, here is one that might be interesting for you as well:
https://bugzilla.xamarin.com/show_bug.cgi?id=59172
P.S.: Here you can find the official guide on Popping Pages from the Navigation Stack.
you should invoke Navigation.PopAsync() to go back

Xamarin Forms: how not reload ListView when pop back

In Xamarin Forms i have a ListView and the following method in Code Behind:
protected async override void OnAppearing()
{
base.OnAppearing();
events.ItemsSource = await App.ServiceManager.GetStream();
}
where
events
is my ListView and fetch data from rest webservice.
When i select an item in the ListView i push a detail page. The problem is that when i pop back to the ListView, the method OnAppearing() is called and make the remote call again.
Instead i'd like that the scroll start from the previous position (before that i push a new page): how can do that?
I think you can simply use a
bool isFirstAppearing = true;
protected async override void OnAppearing()
{
base.OnAppearing();
if(isFirstAppearing) {
isFirstAppearing = false;
events.ItemsSource = await App.ServiceManager.GetStream();
}
}
You can either do a check if its already been loaded, as alessandro Caliaros answer suggests, or an alternative if you want to get fresh data but still be scrolled in the same position, you can add code in onappearing to set the scroll position to be the same as it was before:
var currentYPosition = _scrollView.ScrollY;
await _scrollView.ScrollToAsync(_scrollView.ScrollX, currentYPosition, true);

How to load MainPage when goBack(); form SecondPage?

I use NavigationService.Navigate("..."). But I want to load MainPage again when I click the Back button by event goBack();
In your goBack method you can use the NavigationService.GoBack() call to move from SecondPage back to the MainPage. You can view all the Navigation methods available to you on MSDN.
You can override the method OnBackKeyPress, and inside the method write code shown below, it ll navigate to MainPage.xaml
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
}
If you are using binding do this:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
App.ViewModel.LoadData();
}
And in MainViewModel.cs
public void LoadData()
{
Items.Clear();
this.Items.Add(new ItemViewModel() { LineOne = "runtime one", LineTwo = "Data info 2" });
this.IsDataLoaded = true; }
Like Nigel said, you can use NavigationService.GoBack() however this will only work if you went from the MainPage to the second page.
The only other way to do this is how you have mentioned using NavigationService.Navigate(uri).
Override the navigated to event
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (PhoneApplicationService.Current.State["msg"].ToString() == "from page2")
{
// do something when its comming from page2
}
base.OnNavigatedTo(e);
}
Now that will trigger every time its navigated to but you could send some parameters so you know what to depending on what page it came from.
PhoneApplicationService.Current.State["msg"] = "from page2";
NavigationService.Navigate(new Uri("/MainPage.xaml?msg=", UriKind.Relative));
There are two ways to get back to your MainPage.
(First Method) Override the OnBackKeyPress() and write the following snippet inside it.
NavigationService.GoBack();
Note :
This will move to the MainPage only if the MainPage is the previous page in your Navigation history.
(Second Method) Override the OnBackKeyPress() and write the following snippet inside it.
NavigationService.Navigation(new Url("/MainPage.xaml",UriKind.Relative));
Note :
This will create a New MainPage and navigates to it. So if you navigated from MainPage to SecondPage and if you navigate again to MainPage using the above snippet, you will be having two MainPage in your Navigation history.
So, use any one of the snippet according to your scenario.
if WP7 or WP8 : NavigationService.GoBack()
if WP8.1 : Frame.GoBack();
and you can Override the navigated to event
protected override void
OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) {
// do nothing }
I don't recommend overriding the OnBackKeyPress method and calling NavigationService.Navigate method within it as it may mess up your page back stack.
I assume your app has more than 2 pages. Otherwise you should just call NavigateService.GoBack() as others have recommended.
Example
Start on MainPage (backstack: empty)
Navigate to SecondPage (backstack: MainPage)
Navigate to ThirdPage (backstack: SecondPage, MainPage)
Click the back button (overridden) and you are taken to MainPage (backstack: ThirdPage, SecondPage, MainPage)
Click the back button and you are taken to the ThirdPage (backstack: SecondPage, MainPage). This is not the expected behaviour as the application should have exited.
Now you're stuck in a back button loop.
Solution
Override OnNavigatingFrom and remove any of the backstack entries you don't want the user to go to. You can either allow the user to press the back button to get back to the MainPage from the ThirdPage or you can call NavigationService.GoBack().
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
base.OnNavigatingFrom(e);
// Remove all backstack entries except for the first one
while(NavigationService.BackStack.Count() > 1)
{
NavigationService.RemoveBackEntry();
}
}

Resources