Xamarin.Forms Pagine modali

Xamarin.Forms fornisce supporto per le pagine modali. Una pagina modale richiede agli utenti il completamento di un'attività indipendente, dalla quale non è possibile spostarsi fino a quando non viene completata o annullata. Questo articolo illustra come spostarsi tra pagine modali.

Questo articolo tratta gli argomenti seguenti:

Panoramica

Una pagina modale può essere uno qualsiasi dei tipi di pagina supportati da Xamarin.Forms. Per visualizzare una pagina modale, l'applicazione ne eseguirà il push nello stack modale, in cui diventerà la pagina attiva, come illustrato nel diagramma seguente:

Push di una pagina nello stack modale

Per tornare alla pagina precedente, l'applicazione preleverà la pagina corrente dallo stack modale e la nuova pagina in primo piano diventa la pagina attiva, come illustrato nel diagramma seguente:

Prelievo di una pagina dallo stack modale

Esecuzione degli spostamenti

I metodi di navigazione modale sono esposti dalla proprietà Navigation in qualsiasi tipo derivato Page. Questi metodi offrono la possibilità di eseguire il push delle pagine modali nello stack modale e di prelevare le pagine modali dallo stack modale.

La proprietà Navigation espone anche una proprietà ModalStack dalla quale è possibile ottenere le pagine modali nello stack modale. Tuttavia non esiste nessun concetto di gestione modale dello stack o di prelievo e attivazione della pagina radice nella navigazione modale. Queste operazioni non sono supportate in tutti i casi sulle piattaforme sottostanti.

Nota

Per la navigazione modale nelle pagine non è necessaria un'istanza di NavigationPage.

Push delle pagine nello stack modale

Per passare a ModalPage, è necessario richiamare il metodo PushModalAsync sulla proprietà Navigation della pagina corrente, come illustrato nell'esempio di codice seguente:

async void OnItemSelected (object sender, SelectedItemChangedEventArgs e)
{
  if (listView.SelectedItem != null) {
    var detailPage = new DetailPage ();
    ...
    await Navigation.PushModalAsync (detailPage);
  }
}

In questo modo viene attivato il push dell'istanza di ModalPage nello stack modale, in cui diventa la pagina attiva, a condizione che sia stato selezionato un elemento nel controllo ListView per l'istanza di MainPage. L'istanza di ModalPage è illustrata negli screenshot seguenti:

Esempio di pagina modale

Quando si richiama PushModalAsync, si verificano gli eventi seguenti:

  • Per la pagina che chiama PushModalAsync viene richiamato l'override di OnDisappearing, a condizione che la piattaforma sottostante non sia Android.
  • Per la pagina di destinazione dello spostamento viene richiamato l'override di OnAppearing.
  • L'attività PushAsync viene completata.

Tuttavia, l'ordine preciso in cui si verificano questi eventi è dipendente dalla piattaforma. Per altre informazioni, vedere il capitolo 24 del libro di Xamarin.Forms Charles Petzold.

Nota

Le chiamate degli override di OnDisappearing e OnAppearing non possono essere considerate come indicazioni garantite dell'avvenuto spostamento tra le pagine. Ad esempio, in iOS l'override di OnDisappearing viene chiamato per la pagina attiva quando l'applicazione viene terminata.

Prelievo delle pagine dallo stack modale

La pagina attiva può essere prelevata dallo stack modale premendo il pulsante Indietro del dispositivo, indipendentemente dal fatto che sia un pulsante fisico del dispositivo o un pulsante su schermo.

Per tornare a livello di codice alla pagina originale, l'istanza ModalPage deve chiamare il metodo PopModalAsync, come illustrato nell'esempio di codice seguente:

async void OnDismissButtonClicked (object sender, EventArgs args)
{
  await Navigation.PopModalAsync ();
}

Di conseguenza, l'istanza di ModalPage viene rimossa dallo stack modale e la nuova pagina in primo piano diventa la pagina attiva. Quando si richiama PopModalAsync, si verificano gli eventi seguenti:

  • Per la pagina che chiama PopModalAsync viene richiamato l'override di OnDisappearing.
  • Per la pagina a cui si ritorna viene richiamato l'override di OnAppearing, a condizione che la piattaforma sottostante non sia Android.
  • L'attività PopModalAsync viene completata.

Tuttavia, l'ordine preciso in cui si verificano questi eventi è dipendente dalla piattaforma. Per altre informazioni, vedere il capitolo 24 del libro di Xamarin.Forms Charles Petzold.

Disabilitazione del pulsante Indietro

In Android, l'utente può sempre tornare alla pagina precedente premendo il pulsante Indietro standard sul dispositivo. Se la pagina modale richiede all'utente di completare un'attività indipendente prima di lasciare la pagina, l'applicazione deve disabilitare il pulsante Indietro. Questa operazione può essere effettuata eseguendo l'override del metodo Page.OnBackButtonPressed nella pagina modale. Per altre informazioni, vedere il capitolo 24 del libro di Xamarin.Forms Charles Petzold.

Animazione delle transizioni di pagina

La proprietà Navigation di ogni pagina offre anche metodi di push e di prelievo sottoposti a override, che includono un parametro boolean che controlla la visualizzazione di un'animazione di pagina durante gli spostamenti, come illustrato nell'esempio di codice seguente:

async void OnNextPageButtonClicked (object sender, EventArgs e)
{
  // Page appearance not animated
  await Navigation.PushModalAsync (new DetailPage (), false);
}

async void OnDismissButtonClicked (object sender, EventArgs args)
{
  // Page appearance not animated
  await Navigation.PopModalAsync (false);
}

L'impostazione del parametro boolean su false disabilita l'animazione per la transizione di pagina, mentre l'impostazione del parametro su true abilita l'animazione per la transizione di pagina, a condizione che sia supportata dalla piattaforma sottostante. Tuttavia, i metodi di push e prelievo senza questo parametro abilitano l'animazione per impostazione predefinita.

Passaggio di dati durante gli spostamenti

In alcuni casi, una pagina deve passare dati a un'altra pagina durante gli spostamenti. Due tecniche per questa operazione sono il passaggio dei dati tramite un costruttore di pagina e l'impostazione di BindingContext della nuova pagina sui dati. Di seguito verranno descritti entrambi.

Passaggio dei dati tramite un costruttore di pagina

La tecnica più semplice per il passaggio di dati a un'altra pagina durante gli spostamenti è tramite un parametro del costruttore di pagina, come illustrato nell'esempio di codice seguente:

public App ()
{
  MainPage = new MainPage (DateTime.Now.ToString ("u")));
}

Questo codice crea un'istanza di MainPage, passando la data e l'ora correnti in formato ISO8601.

L'istanza di MainPage riceve i dati tramite un parametro del costruttore, come illustrato nell'esempio di codice seguente:

public MainPage (string date)
{
  InitializeComponent ();
  dateLabel.Text = date;
}

I dati vengono quindi visualizzati nella pagina impostando la proprietà Label.Text.

Passaggio dei dati tramite BindingContext

Un approccio alternativo per passare dati a un'altra pagina durante gli spostamenti consiste nell'impostare BindingContext della nuova pagina sui dati, come illustrato nell'esempio di codice seguente:

async void OnItemSelected (object sender, SelectedItemChangedEventArgs e)
{
  if (listView.SelectedItem != null) {
    var detailPage = new DetailPage ();
    detailPage.BindingContext = e.SelectedItem as Contact;
    listView.SelectedItem = null;
    await Navigation.PushModalAsync (detailPage);
  }
}

Questo codice imposta BindingContext dell'istanza di DetailPage sull'istanza di Contact e quindi passa a DetailPage.

DetailPage usa quindi il data binding per visualizzare i dati dell'istanza di Contact, come illustrato nell'esempio di codice XAML seguente:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ModalNavigation.DetailPage">
    <ContentPage.Padding>
      <OnPlatform x:TypeArguments="Thickness">
        <On Platform="iOS" Value="0,40,0,0" />
      </OnPlatform>
    </ContentPage.Padding>
    <ContentPage.Content>
        <StackLayout HorizontalOptions="Center" VerticalOptions="Center">
            <StackLayout Orientation="Horizontal">
                <Label Text="Name:" FontSize="Medium" HorizontalOptions="FillAndExpand" />
                <Label Text="{Binding Name}" FontSize="Medium" FontAttributes="Bold" />
            </StackLayout>
              ...
            <Button x:Name="dismissButton" Text="Dismiss" Clicked="OnDismissButtonClicked" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

L'esempio di codice seguente illustra come è possibile implementare il data binding in C#:

public class DetailPageCS : ContentPage
{
  public DetailPageCS ()
  {
    var nameLabel = new Label {
      FontSize = Device.GetNamedSize (NamedSize.Medium, typeof(Label)),
      FontAttributes = FontAttributes.Bold
    };
    nameLabel.SetBinding (Label.TextProperty, "Name");
    ...
    var dismissButton = new Button { Text = "Dismiss" };
    dismissButton.Clicked += OnDismissButtonClicked;

    Thickness padding;
    switch (Device.RuntimePlatform)
    {
        case Device.iOS:
            padding = new Thickness(0, 40, 0, 0);
            break;
        default:
            padding = new Thickness();
            break;
    }

    Padding = padding;
    Content = new StackLayout {
      HorizontalOptions = LayoutOptions.Center,
      VerticalOptions = LayoutOptions.Center,
      Children = {
        new StackLayout {
          Orientation = StackOrientation.Horizontal,
          Children = {
            new Label{ Text = "Name:", FontSize = Device.GetNamedSize (NamedSize.Medium, typeof(Label)), HorizontalOptions = LayoutOptions.FillAndExpand },
            nameLabel
          }
        },
        ...
        dismissButton
      }
    };
  }

  async void OnDismissButtonClicked (object sender, EventArgs args)
  {
    await Navigation.PopModalAsync ();
  }
}

I dati vengono quindi visualizzati nella pagina tramite una serie di controlli Label.

Per altre informazioni sul data binding, vedere Data Binding Basics (Nozioni di base sul data binding).

Riepilogo

In questo articolo è stato illustrato come spostarsi tra pagine modali. Una pagina modale richiede agli utenti il completamento di un'attività indipendente, dalla quale non è possibile spostarsi fino a quando non viene completata o annullata.