webentwicklung-frage-antwort-db.com.de

Wie kann ich die Schaltfläche "Zurück" der Navigationsleiste abfangen, auf die in Xamarin Forms geklickt wurde?

Ich habe eine Xamarin-Formularseite, auf der ein Benutzer einige Daten in einem Formular aktualisieren kann. Ich muss die Schaltfläche "Zurück" in der Navigationsleiste abfangen. Klicken Sie auf diese Schaltfläche, um den Benutzer zu warnen, wenn einige Daten nicht gespeichert wurden.

Ich kann die Schaltfläche "Zurück" der Hardware-Leiste abfangen, die in Android mit der Funktion "Android.MainActivity.OnBackPressed()" angeklickt wurde. Dieses Ereignis wird jedoch nur ausgelöst, wenn die Schaltfläche "Zurück" der Hardware-Leiste angeklickt wurde, nicht wenn die Schaltfläche "Zurück" der Navigationsleiste angeklickt wurde.

Ich habe auch versucht, Xamarin.Forms.NavigationPageOnBackButtonPressed() zu überschreiben, aber es funktioniert nicht. Warum? Hat jemand dieses Problem bereits gelöst?

Ich habe auch versucht, OnDisappear() zu überschreiben. Es gibt zwei Probleme:

  1. Die Seite ist schon optisch verschwunden, also das "Bist du sicher?" Das Dialogfeld wird über der vorherigen Seite angezeigt.
  2. Die Zurück-Aktion kann nicht abgebrochen werden.

Ist es also möglich, das Drücken der Zurück-Taste in der Navigationsleiste abzufangen?

12
Amrut

Ich konnte ein Bestätigungsdialogfeld anzeigen, in dem die Navigation abgebrochen werden konnte, indem die folgenden Methoden in FormsApplicationActivity überschrieben wurden. 

  // 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();
     }
  }

Der navigator.CurrentPage ist ein Wrapper für den INavigation-Dienst. Ich muss die Navigation von modalen Seiten nicht abbrechen, daher verwende ich nur den NavigationStack.

this.navigation.NavigationStack[this.navigation.NavigationStack.Count - 1];
8
barry

Das einfachste, wie @JordanMazurke auch etwas erwähnt, da das Ereignis für die Zurück-Schaltfläche derzeit nicht gehandhabt werden kann (außer der physischen Zurück-Schaltfläche für Android), ist entweder

  1. NavigationPage.ShowHasBackButton(this, false)
  2. Drücken einer Modal anstelle einer Page

Danach können Sie eine ActionbarItem hinzufügen, von der aus Sie die Event bearbeiten können.

Ich habe persönlich mit dem iOS-Team von Xamarin zu diesem Thema gesprochen, und sie sagten mir im Grunde, dass wir keine Unterstützung für die Handhabung der Event für die BackButtonPressed in der NavigationBar erwarten sollten. Der Grund dafür ist, dass es unter iOS schlecht ist, eine Nachricht zu erhalten, wenn Back gedrückt wird. 

3
Demitrian

Dies ist eine von Natur aus schwierige Aufgabe und die einzige Möglichkeit, wie ich es umgehen konnte, bestand darin, die Zurück-Schaltfläche vollständig zu entfernen und dann die Rückwärtsnavigation über eine 'Speichern'-Schaltfläche auszuführen. 

Ich habe eine kurze Suche im Xamarin.Forms-Forum durchgeführt und Folgendes wurde vorgeschlagen:

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

Der Link für den Beitrag lautet wie folgt:

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

0
JordanMazurke

Wie schon gesagt - Sie können dies nicht plattformübergreifend tun. Sie können jedoch nativ mit wohl nicht so viel Aufwand umgehen: https://theconfuzedsourcecode.wordpress.com/2017/03/12/lets-override-navigation-bar-back-button-click-in-xamarin- Formen/

Der Artikel behandelt iOS und Android. Wenn Sie ein UWP-Projekt haben, müssen Sie Ihre eigene Lösung dafür finden.

Edit: Hier ist die UWP-Lösung! Es erwies sich als ziemlich einfach - es gibt nur einen Zurück-Button, der von Forms unterstützt wird, sodass Sie nur OnBackButtonPressed von ContentPage überschreiben müssen:

    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);
        }           
    }
0
AXE