Xamarin.Forms Approfondimento di avvio rapido

Nella guida Xamarin.Forms introduttivaè stata compilata l'applicazione Notes. Questo articolo esamina ciò che è stato creato per comprendere i concetti fondamentali del funzionamento delle Xamarin.Forms applicazioni Shell.

Introduzione a Visual Studio

Visual Studio organizza il codice in Soluzioni e progetti. Una soluzione è un contenitore per uno o più progetti. Un progetto può essere un'applicazione, una libreria di supporto, un'applicazione di test e altro ancora. L'applicazione Notes è costituita da una soluzione contenente tre progetti, come illustra lo screenshot seguente:

Visual Studio Esplora soluzioni.

I progetti sono:

  • Notes: progetto di libreria .NET Standard che contiene tutto il codice condiviso e l'interfaccia utente condivisa.
  • Notes.Android: progetto che contiene il codice specifico di Android ed è il punto di ingresso per l'applicazione Android.
  • Notes.iOS: progetto che contiene il codice specifico di iOS ed è il punto di ingresso per l'applicazione iOS.

Anatomia di Xamarin.Forms un'applicazione

Lo screenshot seguente illustra il contenuto del progetto di libreria .NET Standard Notes in Visual Studio:

Phoneword .NET Standard Project Contenuto.

Il progetto ha un nodo Dipendenze contenente i nodi NuGet e SDK:

  • NuGet – i pacchetti , , Newtonsoft.Jssu e Xamarin.Forms Xamarin.Essentials sqlite-net-pcl NuGet che sono stati aggiunti al progetto.
  • SDKNETStandard.Librarymetapacchetto che fa riferimento al set completo di NuGet pacchetti che definiscono .NET Standard.

Introduzione a Visual Studio per Mac

Visual Studio per Mac segue la Visual Studio pratica di organizzazione del codice in Soluzioni e progetti. Una soluzione è un contenitore per uno o più progetti. Un progetto può essere un'applicazione, una libreria di supporto, un'applicazione di test e altro ancora. L'applicazione Notes è costituita da una soluzione contenente tre progetti, come illustra lo screenshot seguente:

Visual Studio per Mac Riquadro della soluzione.

I progetti sono:

  • Notes: progetto di libreria .NET Standard che contiene tutto il codice condiviso e l'interfaccia utente condivisa.
  • Notes.Android: progetto che contiene il codice specifico di Android ed è il punto di ingresso per le applicazioni Android.
  • Notes.iOS: progetto che contiene il codice specifico di iOS ed è il punto di ingresso per le applicazioni iOS.

Anatomia di Xamarin.Forms un'applicazione

Lo screenshot seguente illustra il contenuto del progetto di libreria .NET Standard Notes in Visual Studio per Mac:

Phoneword .NET Standard Library Project Contenuto.

Il progetto ha un nodo Dipendenze contenente i nodi NuGet e SDK:

  • NuGet – i pacchetti , , Newtonsoft.Jssu e Xamarin.Forms Xamarin.Essentials sqlite-net-pcl NuGet che sono stati aggiunti al progetto.
  • SDKNETStandard.Librarymetapacchetto che fa riferimento al set completo di NuGet pacchetti che definiscono .NET Standard.

Il progetto è costituito anche da più file:

  • Data\NoteDatabase.cs: questa classe contiene il codice per creare il database, leggere i dati dal database, scrivere i dati in esso ed eliminarli.
  • Models\Note.cs: questa classe definisce un modello Note le cui istanze archiviano i dati relativi a ogni nota nell'applicazione.
  • Views\AboutPage.xaml: markup XAML per la AboutPage classe, che definisce l'interfaccia utente per la pagina about.
  • Views\AboutPage.xaml.cs: code-behind per la classe , che contiene la logica di business eseguita quando l'utente AboutPage interagisce con la pagina.
  • Views\NotesPage.xaml: markup XAML per la classe, che definisce l'interfaccia utente per la pagina visualizzata NotesPage all'avvio dell'applicazione.
  • Views\NotesPage.xaml.cs: code-behind per la classe , che contiene la logica di business eseguita quando l'utente NotesPage interagisce con la pagina.
  • Views\NoteEntryPage.xaml: markup XAML per la classe, che definisce l'interfaccia utente per la pagina visualizzata quando l'utente NoteEntryPage immette una nota.
  • Views\NoteEntryPage.xaml.cs: code-behind per la classe , che contiene la logica di business eseguita quando l'utente NoteEntryPage interagisce con la pagina.
  • App.xaml: markup XAML per la classe App, che definisce un dizionario risorse per l'applicazione.
  • App.xaml.cs: code-behind per la classe, responsabile della creazione di istanze dell'applicazione Shell e della gestione degli eventi del ciclo App di vita dell'applicazione.
  • AppShell.xaml: markup XAML per la AppShell classe , che definisce la gerarchia visiva dell'applicazione.
  • AppShell.xaml.cs: code-behind per la classe , che crea una route per l'oggetto in modo che possa essere AppShell NoteEntryPage passata a livello di codice.
  • AssemblyInfo.cs: questo file contiene un attributo dell'applicazione relativo al progetto, applicato a livello di assembly.

Per altre informazioni sull'anatomia di un'applicazione Xamarin.iOS, vedere l'analisi dettagliata di un'applicazione Xamarin.iOS. Per altre informazioni sull'anatomia di un'applicazione Xamarin.Android, vedere l'analisi dettagliata di un'applicazione Xamarin.Android.

Architettura e concetti fondamentali dell'applicazione

Xamarin.FormsUn'applicazione è progettata come un'applicazione multipiattaforma tradizionale. Il codice condiviso in genere viene inserito in una libreria .NET Standard e le applicazioni specifiche della piattaforma usano il codice condiviso. Il diagramma seguente illustra una panoramica di questa relazione per l'applicazione Notes:

Architettura delle note.

Per ottimizzare il riutilizzo del codice di avvio, le applicazioni hanno una singola classe denominata responsabile della creazione di istanze dell'applicazione in ogni piattaforma, come illustrato Xamarin.Forms App nell'esempio di codice seguente:

using Xamarin.Forms;

namespace Notes
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
            MainPage = new AppShell();
        }
        // ...
    }
}

Questo codice imposta MainPage la proprietà della classe App AppShell sull'oggetto . La AppShell classe definisce la gerarchia visiva dell'applicazione. Shell accetta questa gerarchia visiva e produce l'interfaccia utente. Per altre informazioni sulla definizione della gerarchia visiva dell'applicazione, vedere Gerarchia di oggetti visivi dell'applicazione.

Il file AssemblyInfo.cs contiene inoltre un singolo attributo dell'applicazione, applicato a livello di assembly:

using Xamarin.Forms.Xaml;

[assembly: XamlCompilation(XamlCompilationOptions.Compile)]

XamlCompilationL'attributo attiva il compilatore XAML, in modo che XAML sia compilato direttamente nel linguaggio intermedio. Per altre informazioni, vedere XAML Compilation (Compilazione XAML).

<a name="launch-the-application-on-each-platform">Avviare l'applicazione in ogni piattaforma

La modalità di avvio dell'applicazione in ogni piattaforma è specifica per la piattaforma.

iOS

Per avviare la Xamarin.Forms pagina iniziale in iOS, il progetto Notes.iOS definisce la classe che eredita dalla classe AppDelegate FormsApplicationDelegate :

namespace Notes.iOS
{
    [Register(&quot;AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new App());
            return base.FinishedLaunching(app, options);
        }
    }
}

FinishedLaunchingL'override inizializza il framework chiamando il metodo Xamarin.Forms Init . In questo modo l'implementazione specifica di iOS di viene caricata nell'applicazione prima che il controller di visualizzazione radice venga Xamarin.Forms impostato dalla chiamata al metodo LoadApplication .

Android

Per avviare la pagina iniziale in Android, il progetto Notes.Android include il codice che crea un con l'attributo , con l'attività che Xamarin.Forms Activity eredita dalla classe MainLauncher FormsAppCompatActivity :

namespace Notes.Droid
{
    [Activity(Label = "Notes",
              Icon = "@mipmap/icon",
              Theme = "@style/MainTheme",
              MainLauncher = true,
              ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());
        }
    }
}

OnCreateL'override inizializza il framework chiamando il metodo Xamarin.Forms Init . In questo modo l'implementazione specifica di Android di Xamarin.Forms viene caricata nell'applicazione prima del Xamarin.Forms caricamento dell'applicazione.

Gerarchia dell'oggetto visivo dell'applicazione

Xamarin.Forms Le applicazioni shell definiscono la gerarchia visiva dell'applicazione in una classe che sottoclassa la Shell classe . Nell'applicazione Notes si tratta della Appshell classe :

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
       xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
       xmlns:views="clr-namespace:Notes.Views"
       x:Class="Notes.AppShell">
    <TabBar>
        <ShellContent Title="Notes"
                      Icon="icon_feed.png"
                      ContentTemplate="{DataTemplate views:NotesPage}" />
        <ShellContent Title="About"
                      Icon="icon_about.png"
                      ContentTemplate="{DataTemplate views:AboutPage}" />
    </TabBar>
</Shell>

Questo codice XAML è costituito da due oggetti principali:

  • TabBar. Rappresenta la barra delle schede inferiore e deve essere usato quando il modello di navigazione TabBar per l'applicazione usa le schede inferiore. L'oggetto TabBar è un elemento figlio dell'oggetto Shell.
  • ShellContent, che rappresenta gli ContentPage oggetti per ogni scheda in TabBar . Ogni ShellContent oggetto è un elemento figlio dell'oggetto TabBar .

Questi oggetti non rappresentano alcuna interfaccia utente, ma piuttosto l'organizzazione della gerarchia visiva dell'applicazione. La shell accetta questi oggetti e genera l'interfaccia utente di navigazione per il contenuto. Pertanto, la classe definisce due pagine che AppShell possono essere esplorabili dalle schede inferiore. Le pagine vengono create su richiesta, in risposta alla navigazione.

Per altre informazioni sulle applicazioni Shell, vedere Xamarin.Forms Shell.

Interfaccia utente

Esistono diversi gruppi di controllo usati per creare l'interfaccia utente di Xamarin.Forms un'applicazione:

  1. Pagine: Xamarin.Forms le pagine rappresentano schermate di applicazioni mobili multipiattaforma. L'applicazione Notes usa ContentPage la classe per visualizzare singole schermate. Per altre informazioni sulle pagine, vedere Xamarin.Forms Pagine.
  2. Visualizzazioni: Xamarin.Forms le visualizzazioni sono i controlli visualizzati nell'interfaccia utente, ad esempio etichette, pulsanti e caselle di immissione di testo. L'applicazione Notes completata usa CollectionView le Editor visualizzazioni , e Button . Per altre informazioni sulle viste, vedere Xamarin.Forms Viste.
  3. Layout: Xamarin.Forms i layout sono contenitori usati per comporre viste in strutture logiche. L'applicazione Notes usa la classe per disporre le visualizzazioni in uno StackLayout stack verticale e la classe per disporre i pulsanti Grid orizzontalmente. Per altre informazioni sui layout, vedere Xamarin.Forms Layout.

In fase di runtime ogni controllo viene mappato al controllo nativo equivalente, che viene restituito nel rendering.

Layout

L'applicazione Notes usa per semplificare lo sviluppo di applicazioni multipiattaforma disponendo automaticamente le visualizzazioni sullo schermo StackLayout indipendentemente dalle dimensioni dello schermo. Gli elementi figlio vengono posizionati uno dopo l'altro, orizzontalmente o verticalmente, nell'ordine in cui sono stati aggiunti. La quantità di spazio che userà dipende dalla modalità di impostazione delle proprietà e , ma per impostazione predefinita StackLayout HorizontalOptions VerticalOptions StackLayout tenterà di usare l'intera schermata.

Il codice XAML seguente mostra un esempio di uso di per StackLayout il layout di NoteEntryPage :

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Notes.Views.NoteEntryPage"
             Title="Note Entry">
    ...    
    <StackLayout Margin="{StaticResource PageMargin}">
        <Editor Placeholder="Enter your note"
                Text="{Binding Text}"
                HeightRequest="100" />
        <Grid>
            ...
        </Grid>
    </StackLayout>    
</ContentPage>

Per impostazione StackLayout predefinita, presuppone un orientamento verticale. Tuttavia, può essere modificato in un orientamento orizzontale impostando la StackLayout.Orientation proprietà sul membro StackOrientation.Horizontal dell'enumerazione .

Nota

Le dimensioni delle visualizzazioni possono essere impostate tramite le proprietà HeightRequest e WidthRequest.

Per altre informazioni sulla StackLayout classe , vedere Xamarin.Forms StackLayout.

Risposta all'interazione dell'utente

Un oggetto definito in XAML può generare un evento che viene gestito nel file code-behind. Nell'esempio di codice seguente viene illustrato il metodo nel code-behind per la classe , che viene eseguito in risposta all'attivazione OnSaveButtonClicked NoteEntryPage dell'evento sul Clicked pulsante Salva.

async void OnSaveButtonClicked(object sender, EventArgs e)
{
    var note = (Note)BindingContext;
    note.Date = DateTime.UtcNow;
    if (!string.IsNullOrWhiteSpace(note.Text))
    {
        await App.Database.SaveNoteAsync(note);
    }
    await Shell.Current.GoToAsync("..");
}

Il metodo OnSaveButtonClicked salva la nota nel database e torna alla pagina precedente. Per altre informazioni sulla navigazione, vedere Navigazione.

Nota

Il file code-behind per una classe XAML è in grado di accedere a un oggetto definito in XAML usando il nome assegnato con l'attributo x:Name. Il valore assegnato a questo attributo ha le stesse regole delle variabili di C#, poiché deve iniziare con una lettera o un carattere di sottolineatura e non contenere spazi incorporati.

L'associazione del pulsante di salvataggio al metodo OnSaveButtonClicked si verifica nel markup XAML per la classe NoteEntryPage:

<Button Text="Save"
        Clicked="OnSaveButtonClicked" />

Elenchi

è CollectionView responsabile della visualizzazione di una raccolta di elementi in un elenco. Per impostazione predefinita, gli elementi dell'elenco vengono visualizzati verticalmente e ogni elemento viene visualizzato in una singola riga.

Nell'esempio di codice seguente viene CollectionView illustrato da NotesPage :

<CollectionView x:Name="collectionView"
                Margin="{StaticResource PageMargin}"
                SelectionMode="Single"
                SelectionChanged="OnSelectionChanged">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Vertical"
                           ItemSpacing="10" />
    </CollectionView.ItemsLayout>
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <StackLayout>
                <Label Text="{Binding Text}"
                       FontSize="Medium" />
                <Label Text="{Binding Date}"
                       TextColor="{StaticResource TertiaryColor}"
                       FontSize="Small" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

Il layout di ogni riga in è definito all'interno dell'elemento e usa data binding per visualizzare le note CollectionView CollectionView.ItemTemplate recuperate dall'applicazione. La CollectionView.ItemsSource proprietà è impostata sull'origine dati, in NotesPage.xaml.cs:

protected override async void OnAppearing()
{
    base.OnAppearing();

    collectionView.ItemsSource = await App.Database.GetNotesAsync();
}

Questo codice popola l'oggetto con eventuali note archiviate nel database e CollectionView viene eseguito quando viene visualizzata la pagina.

Quando viene selezionato un elemento in CollectionView , viene SelectionChanged generato l'evento . Un gestore eventi, denominato OnSelectionChanged, viene eseguito quando viene generato l'evento:

async void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.CurrentSelection != null)
    {
        // ...
    }
}

SelectionChangedL'evento può accedere all'oggetto associato all'elemento tramite la e.CurrentSelection proprietà .

Per altre informazioni sulla CollectionView classe , vedere Xamarin.Forms CollectionView.

La navigazione in un'applicazione shell avviene specificando un URI a cui passare. Gli URI di navigazione hanno tre componenti:

  • Una route, che definisce il percorso del contenuto che fa parte della gerarchia visiva della shell.
  • Pagina . Se le pagine non sono presenti nella gerarchia visiva della shell, è possibile eseguirne il push nello stack di navigazione da qualsiasi posizione all'interno di un'applicazione shell. Ad esempio, non è definito nella gerarchia visiva shell, ma può essere inserito nello NoteEntryPage stack di navigazione in base alle esigenze.
  • Uno o più parametri di query. I parametri di query sono parametri che è possibile passare alla pagina di destinazione durante la navigazione.

Un URI di navigazione non deve includere tutti e tre i componenti, ma quando esegue la struttura è: //route/page?queryParameters

Nota

Le route possono essere definite sugli elementi nella gerarchia visiva shell tramite la Route proprietà . Tuttavia, se la proprietà non è impostata, ad esempio nell'applicazione Notes, viene generata una route in Route fase di esecuzione.

Per altre informazioni sull'esplorazione della shell, vedere Xamarin.Forms Navigazione della shell.

Registrare le route

Per passare a una pagina che non esiste nella gerarchia visiva shell, è necessario prima registrarla con il sistema di routing shell. utilizzando il Routing.RegisterRoute metodo . Nell'applicazione Notes questo si verifica nel AppShell costruttore :

public partial class AppShell : Shell
{
    public AppShell()
    {
        // ...
        Routing.RegisterRoute(nameof(NoteEntryPage), typeof(NoteEntryPage));
    }
}

In questo esempio una route denominata NoteEntryPage viene registrata nel tipo NoteEntryPage . È quindi possibile passare a questa pagina usando la navigazione basata su URI, da qualsiasi punto dell'applicazione.

Eseguire la navigazione

La navigazione viene eseguita dal GoToAsync metodo , che accetta un argomento che rappresenta la route a cui passare:

await Shell.Current.GoToAsync("NoteEntryPage");

In questo esempio si NoteEntryPage passa a .

Importante

Quando si passa a una pagina che non si trova nella gerarchia visiva shell, viene creato uno stack di navigazione.

Quando si passa a una pagina, i dati possono essere passati alla pagina come parametro di query:

async void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (e.CurrentSelection != null)
    {
        // Navigate to the NoteEntryPage, passing the ID as a query parameter.
        Note note = (Note)e.CurrentSelection.FirstOrDefault();
        await Shell.Current.GoToAsync($"{nameof(NoteEntryPage)}?{nameof(NoteEntryPage.ItemId)}={note.ID.ToString()}");
    }
}

In questo esempio viene recuperato l'elemento attualmente selezionato in e si passa a , con il valore della proprietà dell'oggetto passato come parametro CollectionView di query alla proprietà NoteEntryPage ID Note NoteEntryPage.ItemId .

Per ricevere i dati passati, NoteEntryPage la classe è decorata con QueryPropertyAttribute

[QueryProperty(nameof(ItemId), nameof(ItemId))]
public partial class NoteEntryPage : ContentPage
{
    public string ItemId
    {
        set
        {
            LoadNote(value);
        }
    }
    // ...
}

Il primo argomento per specifica che la proprietà riceverà i dati passati, con il QueryPropertyAttribute secondo argomento che specifica ItemId l'ID del parametro di query. Pertanto, nell'esempio precedente specifica che la proprietà riceverà i dati passati nel parametro QueryPropertyAttribute di query dall'URI nella chiamata al ItemId ItemId GoToAsync metodo. La ItemId proprietà chiama quindi il metodo per recuperare la nota dal LoadNote dispositivo.

Lo spostamento all'indietro viene eseguito specificando ".." come argomento del GoToAsync metodo :

await Shell.Current.GoToAsync("..");

Per altre informazioni sullo spostamento all'indietro, vedere Navigazione all'indietro.

Associazione dati

Il data binding viene usato per semplificare la visualizzazione Xamarin.Forms e l'interazione di un'applicazione con i relativi dati. Stabilisce una connessione tra l'interfaccia utente e l'applicazione sottostante. La BindableObject classe contiene gran parte dell'infrastruttura per supportare data binding.

Il data binding (o associazione di dati) consente di connettere due oggetti, detti oggetti di origine e di destinazione. L'oggetto di origine visualizza i dati. L'oggetto di destinazione usa (e spesso visualizza) i dati dall'oggetto di origine. Ad esempio, un ( oggetto di destinazione) associa in genere la proprietà Editor a una proprietà pubblica in un oggetto Text string di origine. Il diagramma che segue illustra la relazione di associazione:

Associazione dati.

Il vantaggio principale del data binding sta nel fatto che non è più necessario preoccuparsi della sincronizzazione tra le visualizzazioni e l'origine dati. Le modifiche apportate all'oggetto di origine vengono trasmesse automaticamente in background all'oggetto di destinazione dal framework di associazione. Facoltativamente, le modifiche all'oggetto di destinazione possono anche essere respinte all'oggetto di origine.

La definizione del data binding è un processo in due fasi:

  • La BindingContext proprietà dell'oggetto di destinazione deve essere impostata sull'oggetto di origine.
  • È necessario stabilire un'associazione tra la destinazione e l'origine. In XAML questa operazione viene ottenuta usando l'estensione Binding di markup .

Nell'applicazione Notes la destinazione dell'associazione è l'oggetto che visualizza una Editor nota, mentre l'istanza Note impostata come BindingContext di è NoteEntryPage l'origine dell'associazione. Inizialmente, BindingContext l'oggetto di NoteEntryPage viene impostato quando viene eseguito il costruttore della pagina:

public NoteEntryPage()
{
    // ...
    BindingContext = new Note();
}

In questo esempio, la proprietà della BindingContext pagina è impostata su un nuovo Note quando viene creato NoteEntryPage . In questo modo viene gestito lo scenario di aggiunta di una nuova nota all'applicazione.

Inoltre, è possibile impostare la proprietà della pagina anche quando si verifica lo spostamento in , a condizione che sia stata selezionata una nota BindingContext NoteEntryPage esistente in NotesPage :

[QueryProperty(nameof(ItemId), nameof(ItemId))]
public partial class NoteEntryPage : ContentPage
{
    public string ItemId
    {
        set
        {
            LoadNote(value);
        }

        async void LoadNote(string itemId)
        {
            try
            {
                int id = Convert.ToInt32(itemId);
                // Retrieve the note and set it as the BindingContext of the page.
                Note note = await App.Database.GetNoteAsync(id);
                BindingContext = note;
            }
            catch (Exception)
            {
                Console.WriteLine("Failed to load note.");
            }
        }    
        // ...    
    }
}

In questo esempio, quando si verifica lo spostamento tra pagine, la proprietà della pagina viene impostata sull'oggetto selezionato dopo che BindingContext Note è stata recuperata dal database.

Importante

Anche se la proprietà di ogni oggetto di destinazione può BindingContext essere impostata singolarmente, questa operazione non è necessaria. BindingContext è una proprietà speciale che viene ereditata da tutti gli elementi figlio. Pertanto, quando in è impostato su un'istanza , tutti gli elementi figlio di hanno lo stesso e possono essere associati alle BindingContext ContentPage proprietà pubbliche Note ContentPage BindingContext Note dell'oggetto .

In Editor NoteEntryPage viene quindi associato alla Text proprietà Note dell'oggetto :

<Editor Placeholder="Enter your note"
        Text="{Binding Text}" />

Viene stabilita Editor.Text un'associazione tra la proprietà Text e la proprietà dell'oggetto di origine. Le modifiche apportate nell'Editor vengono propagate automaticamente all'oggetto Note. Analogamente, se vengono apportate modifiche alla proprietà , anche il motore di Note.Text Xamarin.Forms associazione aggiornerà il contenuto di Editor . Questa funzionalità è detta associazione bidirezionale.

Per altre informazioni sui data binding, vedere Xamarin.Forms Data Binding.

Stile

Xamarin.Forms Le applicazioni contengono spesso più elementi visivi con un aspetto identico. L'impostazione dell'aspetto di ogni elemento visivo può essere ripetitiva e soggetta a errori. È invece possibile creare stili che definiscono l'aspetto e applicarli agli elementi visivi necessari.

La Style classe raggruppa una raccolta di valori di proprietà in un unico oggetto che può quindi essere applicato a più istanze di elementi visivi. Gli stili vengono archiviati in ResourceDictionary un oggetto , a livello di applicazione, a livello di pagina o di visualizzazione. Scegliere dove definire un oggetto Style ha effetto su dove può essere usato:

  • Style Le istanze definite a livello di applicazione possono essere applicate in tutta l'applicazione.
  • Style Le istanze definite a livello di pagina possono essere applicate alla pagina e ai relativi elementi figlio.
  • Style Le istanze definite a livello di vista possono essere applicate alla vista e ai relativi elementi figlio.

Importante

Tutti gli stili usati nell'applicazione vengono archiviati nel dizionario risorse dell'applicazione per evitare duplicati. Tuttavia, il codice XAML specifico di una pagina non deve essere incluso nel dizionario risorse dell'applicazione per evitare che le risorse vengano analizzate all'avvio dell'applicazione invece che quando richiesto da una pagina. Per altre informazioni, vedere Ridurre le dimensioni del dizionario risorse dell'applicazione.

Ogni Style istanza contiene una raccolta di uno o più oggetti , ognuno con e Setter Setter Property Value . Property è il nome della proprietà associabile dell'elemento a cui viene applicato lo stile e Value è il valore applicato alla proprietà. L'esempio di codice seguente illustra uno stile da NoteEntryPage:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Notes.Views.NoteEntryPage"
             Title="Note Entry">
    <ContentPage.Resources>
        <!-- Implicit styles -->
        <Style TargetType="{x:Type Editor}">
            <Setter Property="BackgroundColor"
                    Value="{StaticResource AppBackgroundColor}" />
        </Style>
        ...
    </ContentPage.Resources>
    ...
</ContentPage>

Questo stile viene applicato a Editor tutte le istanze della pagina.

Quando si crea Style , la proprietà è sempre TargetType obbligatoria.

Nota

L'applicazione Xamarin.Forms di stili a un'applicazione viene in genere eseguita usando gli stili XAML. Tuttavia, supporta anche l'applicazione di stili agli elementi visivi Xamarin.Forms usando Cascading Style Sheets (CSS). Per altre informazioni, vedere Applicazione di stili alle Xamarin.Forms app Cascading Style Sheets (CSS).

Per altre informazioni sugli stili XAML, vedere Applicazione di stili alle app con stili Xamarin.Forms XAML.

Test e distribuzione

Visual Studio per Mac e Visual Studio offrono entrambi numerose opzioni per il test e la distribuzione di un'applicazione. Il debug delle applicazioni fa parte del ciclo di vita dello sviluppo delle applicazioni e consente di diagnosticare i problemi del codice. Per altre informazioni, vedere gli articoli relativi all'impostazione di un punto di interruzione, al passaggio attraverso il codice e all'output di informazioni alla finestra del log.

I simulatori sono un ottimo strumento per iniziare a distribuire e testare e offrono funzionalità utili per testare le applicazioni. Tuttavia, gli utenti non useranno l'applicazione finale in un simulatore, quindi le applicazioni devono essere testate nei dispositivi reali presto e spesso. Per altre informazioni sul provisioning dei dispositivi iOS, vedere Provisioning dei dispositivi. Per altre informazioni sul provisioning dei dispositivi Android, vedere Set Up Device for Development (Configurare il dispositivo per lo sviluppo).

Passaggi successivi

Questo approfondimento ha esaminato i concetti fondamentali dello sviluppo di applicazioni tramite Xamarin.Forms Shell. I passaggi suggeriti che seguono includono informazioni sulle funzionalità seguenti:

  • Xamarin.Forms Shell riduce la complessità dello sviluppo di applicazioni per dispositivi mobili fornendo le funzionalità fondamentali richieste dalla maggior parte delle applicazioni per dispositivi mobili. Per altre informazioni, vedere Xamarin.Forms Shell.
  • Esistono diversi gruppi di controllo usati per creare l'interfaccia utente di Xamarin.Forms un'applicazione. Per altre informazioni, vedere Riferimento per i controlli.
  • Il data binding è una tecnica che consente di collegare le proprietà di due oggetti in modo che le modifiche apportate a una proprietà vengano automaticamente riflesse nell'altra proprietà. Per altre informazioni, vedere Data Binding.
  • Xamarin.Forms offre più esperienze di navigazione tra le pagine, a seconda del tipo di pagina in uso. Per altre informazioni, vedere Navigazione.
  • Gli stili consentono di ridurre il markup ripetitivo e di modificare facilmente l'aspetto di un'applicazione. Per altre informazioni, vedere Applicazione di stili alle Xamarin.Forms app.
  • I modelli di dati consentono di definire la presentazione dei dati nelle viste supportate. Per altre informazioni, vedere Data Templates (Modelli di dati).
  • Anche gli effetti consentono la personalizzazione dei controlli nativi in ogni piattaforma. Gli effetti vengono creati nei progetti specifici della piattaforma sottoclassando la classe e vengono utilizzati PlatformEffect collegandoli a un controllo Xamarin.Forms appropriato. Per altre informazioni, vedere Effects (Effetti).
  • Il rendering di ogni pagina, layout e vista viene eseguito in modo diverso su ogni piattaforma usando una classe Renderer che a sua volta crea un controllo nativo, lo dispone sullo schermo e aggiunge il comportamento specificato nel codice condiviso. Gli sviluppatori possono implementare le proprie classi Renderer per personalizzare l'aspetto e/o il comportamento di un controllo. Per altre informazioni, vedere Custom Renderers (Renderer personalizzati).
  • Il codice condiviso può accedere alle funzionalità native tramite la classe DependencyService. Per altre informazioni, vedere Accessing Native Features with DependencyService (Accesso alle funzionalità native con DependencyService).

Altri video di Xamarin sono disponibili su Channel 9 e YouTube.