11

Mam stronę formularza xamarin, gdzie użytkownik może zaktualizować niektóre dane w formularzu. Muszę przechwycić przycisk Wstecz paska nawigacyjnego Kliknij, aby ostrzec użytkownika, jeśli niektóre dane nie zostały zapisane. Jak to zrobić?Jak przechwycić przycisk Wstecz paska nawigacyjnego kliknięty w Xamarin Forms?

Jestem w stanie przechwycić sprzętowy przycisk Wstecz Przycisk kliknięty w systemie Android przy użyciu Android.MainActivity.OnBackPressed(), ale zdarzenie to jest wywoływane tylko na sprzętowym przycisku Wstecz Przycisk kliknięty, a nie Przycisk nawigacyjny Wstecz Przycisk kliknięty.

Próbowałem również zastąpić Xamarin.Forms.NavigationPageOnBackButtonPressed(), ale to nie działa. Czemu? Ktoś już rozwiązał ten problem?

Próbowałem też nadrzędnymi OnDisappear() istnieją dwa problemy: „Czy na pewno”

  1. strona już wizualnie zniknęły więc pojawi się okno dialogowe na poprzedniej stronie.
  2. Nie można anulować działania wstecz.

Czy możliwe jest przechwycenie przycisku wstecznego paska nawigacji?

Odpowiedz

0

Jest to z natury trudne zadanie, a jedynym sposobem, w jaki go pokonałem, było całkowite usunięcie przycisku wstecz, a następnie obsługa nawigacji wstecz z przycisku "zapisz".

Zrobiłem krótki przeszukanie forum Xamarin.Forms oraz następujące Sugerowano:

public override bool OnOptionsItemSelected(Android.Views.IMenuItem item) 
{ 
    return false; 
} 

Link na stanowisko przedstawia się następująco:

https://forums.xamarin.com/discussion/21631/is-there-nay-way-of-cancelling-the-back-button-event-from-the-navigationpage

-1

W Xamarin .Forms, klasa Page ma metodę OnBackButtonPressed(), z której możesz korzystać na wszystkich platformach.

+1

nie powiedzieć, czy przycisk nawigacyjny powrót/ikona jest wciśnięty - tylko jeśli przycisk powrotu systemu jest wciśnięty – noelicus

3

Najprostszy, jak @JordanMazurke również nieco wspomina, ponieważ zdarzenia dla przycisku Wstecz nie mogą być obsługiwane obecnie (inne niż fizycznego przycisku Wstecz na Androida), to albo:

  1. NavigationPage.ShowHasBackButton(this, false)
  2. Pchanie Modal zamiast Page

Następnie można dodać ActionbarItem, z którego można obsługiwać Event.

osobiście rozmawiał z zespołem iOS od Xamarin dotyczące tej kwestii, a oni w zasadzie powiedziano mi, że nie należy spodziewać się wsparcia dla obsługi Event dla BackButtonPressed w NavigationBar. Powodem jest to, że na iOS nie jest dobrze, aby użytkownicy otrzymywali wiadomość po naciśnięciu przycisku Back.

+0

:(to sprawia, że ​​jestem smutny. –

7

Udało mi się wyświetlić okno dialogowe z potwierdzeniem, które może anulować nawigację, zastępując następujące metody w FormsApplicationActivity.

// navigation back button 
    public override bool OnOptionsItemSelected(IMenuItem item) 
    { 
    if (item.ItemId == 16908332) 
    { 
     var currentViewModel = (IViewModel)navigator.CurrentPage.BindingContext; 
     currentViewModel.CanNavigateFromAsync().ContinueWith(t => 
     { 
      if (t.Result) 
      { 
       navigator.PopAsync(); 
      } 
     }, TaskScheduler.FromCurrentSynchronizationContext()); 
     return false; 
    } 
    else 
    { 
     return base.OnOptionsItemSelected(item); 
    } 
    } 

    // hardware back button 
    public async override void OnBackPressed() 
    { 
    var currentViewModel = (IViewModel)navigator.CurrentPage.BindingContext; 

    // could display a confirmation dialog (ex: "Cancel changes?") 
    var canNavigate = await currentViewModel.CanNavigateFromAsync(); 
    if (canNavigate) 
    { 
     base.OnBackPressed(); 
    } 
    } 

Nawigator.CurrentPage jest opakowaniem wokół usługi INavigation. Nie muszę anulować nawigacji ze stron modalnych, więc używam tylko aplikacji NavigationStack.

this.navigation.NavigationStack[this.navigation.NavigationStack.Count - 1]; 
0

Jak już powiedziano - nie można tego zrobić na wielu platformach. Można go jednak obsługiwać natywnie z pewnością niewielkim wysiłkiem: https://theconfuzedsourcecode.wordpress.com/2017/03/12/lets-override-navigation-bar-back-button-click-in-xamarin-forms/

Artykuł dotyczy iOS i Androida. Jeśli masz projekt UWP, musisz wymusić na nim własne rozwiązanie.

Edytuj: Oto rozwiązanie UWP! Faktycznie okazało się całkiem proste - jest tylko jeden przycisk z powrotem i jest obsługiwany przez Form więc po prostu trzeba zastąpić ContentPage za OnBackButtonPressed:

protected override bool OnBackButtonPressed() 
    { 
     if (Device.RuntimePlatform.Equals(Device.UWP)) 
     { 
      OnClosePageRequested(); 
      return true; 
     } 
     else 
     { 
      base.OnBackButtonPressed(); 
      return false; 
     } 
    } 

    async void OnClosePageRequested() 
    { 
     var tdvm = (TaskDetailsViewModel)BindingContext; 
     if (tdvm.CanSaveTask()) 
     { 
      var result = await DisplayAlert("Wait", "You have unsaved changes! Are you sure you want to go back?", "Discard changes", "Cancel"); 

      if (result) 
      { 
       tdvm.DiscardChanges(); 
       await Navigation.PopAsync(true); 
      } 
     } 
     else 
     { 
      await Navigation.PopAsync(true); 
     }   
    } 
Powiązane problemy