Xamarin.Forms Approfondimento della guida introduttiva
Nella guida introduttiva è Xamarin.Forms stata compilata l'applicazione Notes. Questo articolo esamina ciò che è stato creato per comprendere i concetti fondamentali del funzionamento Xamarin.Forms delle applicazioni Shell.
Introduzione a Visual Studio
Visual Studio consente di organizzare 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:
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 un'applicazione Xamarin.Forms
Lo screenshot seguente illustra il contenuto del progetto di libreria .NET Standard Notes in Visual Studio:
Il progetto ha un nodo Dipendenze contenente i nodi NuGet e SDK:
- NuGet: i Xamarin.Formspacchetti NuGet , Newtonsoft.Json Xamarin.Essentialse sqlite-net-pcl aggiunti al progetto.
- SDK :
NETStandard.Library
metapacchetto che fa riferimento al set completo di pacchetti NuGet che definiscono .NET Standard.
Introduzione a Visual Studio per Mac
Visual Studio per Mac segue la prassi di Visual Studio di organizzare 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:
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 un'applicazione Xamarin.Forms
Lo screenshot seguente illustra il contenuto del progetto di libreria .NET Standard Notes in Visual Studio per Mac:
Il progetto ha un nodo Dipendenze contenente i nodi NuGet e SDK:
- NuGet: i Xamarin.Formspacchetti NuGet , Newtonsoft.Json Xamarin.Essentialse sqlite-net-pcl aggiunti al progetto.
- SDK :
NETStandard.Library
metapacchetto che fa riferimento al set completo di pacchetti NuGet 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
AboutPage
classe , che contiene la logica di business eseguita quando l'utente interagisce con la pagina. - Views\NotesPage.xaml : markup XAML per la
NotesPage
classe , che definisce l'interfaccia utente per la pagina visualizzata all'avvio dell'applicazione. - Views\NotesPage.xaml.cs : code-behind per la
NotesPage
classe , che contiene la logica di business eseguita quando l'utente interagisce con la pagina. - Views\NoteEntryPage.xaml : markup XAML per la
NoteEntryPage
classe , che definisce l'interfaccia utente per la pagina visualizzata quando l'utente immette una nota. - Views\NoteEntryPage.xaml.cs : code-behind per la
NoteEntryPage
classe , che contiene la logica di business eseguita quando l'utente 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
App
classe , responsabile della creazione di un'istanza dell'applicazione Shell e della gestione degli eventi del ciclo 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
AppShell
classe , che crea una route per inNoteEntryPage
modo che possa essere spostata 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
Un'applicazione Xamarin.Forms è progettata nello stesso modo di 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:
Per ottimizzare il riutilizzo del codice di avvio, Xamarin.Forms le applicazioni hanno una singola classe denominata App
responsabile della creazione di un'istanza dell'applicazione in ogni piattaforma, come illustrato nell'esempio di codice seguente:
using Xamarin.Forms;
namespace Notes
{
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new AppShell();
}
// ...
}
}
Questo codice imposta la MainPage
proprietà della App
classe sull'oggetto AppShell
. 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 visiva 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)]
L'attributo XamlCompilation
attiva il compilatore XAML, in modo che il codice XAML venga compilato direttamente in linguaggio intermedio. Per altre informazioni, vedere XAML Compilation (Compilazione XAML).
Avviare l'applicazione in ogni piattaforma
La modalità di avvio dell'applicazione in ogni piattaforma è specifica per la piattaforma.
iOS
Per avviare la pagina iniziale Xamarin.Forms in iOS, il progetto Notes.iOS definisce la AppDelegate
classe che eredita dalla FormsApplicationDelegate
classe :
namespace Notes.iOS
{
[Register("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);
}
}
}
L'override FinishedLaunching
inizializza il Xamarin.Forms framework chiamando il Init
metodo . In questo modo l'implementazione specifica di iOS di Xamarin.Forms deve essere caricata nell'applicazione prima che il controller di visualizzazione radice venga impostato dalla chiamata al LoadApplication
metodo .
Android
Per avviare la pagina iniziale Xamarin.Forms in Android, il progetto Notes.Android include il codice che crea un Activity
oggetto con l'attributo , con l'attività MainLauncher
che eredita dalla FormsAppCompatActivity
classe :
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());
}
}
}
L'override OnCreate
inizializza il Xamarin.Forms framework chiamando il Init
metodo . In questo modo, l'implementazione specifica di Android di Xamarin.Forms deve essere caricata nell'applicazione prima del caricamento dell'applicazione Xamarin.Forms .
Gerarchia visiva 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
.TabBar
Rappresenta la barra delle schede inferiore e deve essere usata quando il modello di spostamento per l'applicazione usa schede inferiori. L'oggettoTabBar
è un elemento figlio dell'oggettoShell
.ShellContent
, che rappresenta gliContentPage
oggetti per ogni scheda dell'oggettoTabBar
. OgniShellContent
oggetto è un elemento figlio dell'oggettoTabBar
.
Questi oggetti non rappresentano alcuna interfaccia utente, ma piuttosto l'organizzazione della gerarchia visiva dell'applicazione. Shell prenderà questi oggetti e genererà l'interfaccia utente di spostamento per il contenuto. Pertanto, la AppShell
classe definisce due pagine navigabili dalle schede inferiori. 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 un'applicazione Xamarin.Forms :
- Pagine : Xamarin.Forms le pagine rappresentano schermate dell'applicazione per dispositivi mobili multipiattaforma. L'applicazione Notes usa la classe
ContentPage
per visualizzare una singola schermata. Per altre informazioni sulle pagine, vedere Xamarin.Forms Pagine. - 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 le visualizzazioni
CollectionView
,Editor
eButton
. Per altre informazioni sulle visualizzazioni, vedere Xamarin.Forms Viste. - Layout: i Xamarin.Forms layout sono contenitori usati per comporre visualizzazioni in strutture logiche. L'applicazione Notes usa la classe
StackLayout
per disporre le visualizzazioni in uno stack verticale e la classeGrid
per disporre i pulsanti 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 la classe StackLayout
per semplificare lo sviluppo di applicazioni multipiattaforma disponendo automaticamente le visualizzazioni nella schermata, indipendentemente dalle dimensioni della schermata. Gli elementi figlio vengono posizionati uno dopo l'altro, orizzontalmente o verticalmente, nell'ordine in cui sono stati aggiunti. La quantità di spazio usata dall'elemento StackLayout
dipende dall'impostazione delle proprietà HorizontalOptions
e VerticalOptions
, ma per impostazione predefinita StackLayout
prova a usare l'intero schermo.
Il codice XAML seguente mostra un esempio dell'uso di una classe StackLayout
per 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 predefinita, la classe StackLayout
presuppone un orientamento verticale, che può tuttavia essere sostituito da un orientamento orizzontale impostando la proprietà StackLayout.Orientation
sul membro dell'enumerazione StackOrientation.Horizontal
.
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. L'esempio di codice seguente illustra il metodo OnSaveButtonClicked
nel code-behind per la classe NoteEntryPage
, eseguito in risposta alla generazione dell'evento Clicked
per il pulsante Save.
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 informazioni sullo spostamento tra le pagine, 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.
L'esempio di codice seguente visualizza la classe CollectionView
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 CollectionView
viene definito all'interno dell'elemento CollectionView.ItemTemplate
e usa il data binding per visualizzare le note 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 con CollectionView
tutte le note archiviate nel database e viene eseguito quando viene visualizzata la pagina.
Quando un elemento viene selezionato in CollectionView
, l'evento SelectionChanged
viene generato. Un gestore eventi, denominato OnSelectionChanged
, viene eseguito quando viene generato l'evento:
async void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.CurrentSelection != null)
{
// ...
}
}
L'evento SelectionChanged
può accedere all'oggetto associato all'elemento tramite la e.CurrentSelection
proprietà .
Per altre informazioni sulla CollectionView
classe, vedere Xamarin.Forms CollectionView.
Navigazione
La navigazione in un'applicazione shell avviene specificando un URI a cui passare. Gli URI di spostamento hanno tre componenti:
- Una route, che definisce il percorso del contenuto esistente nell'ambito della gerarchia visiva di Shell.
- Una 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,
NoteEntryPage
non è definito nella gerarchia visiva della shell, ma può essere inserito nello stack di navigazione in base alle esigenze. - Uno o più parametri di query. I parametri di query possono essere passati alla pagina di destinazione durante lo spostamento.
Un URI di spostamento non deve includere tutti e tre i componenti, ma quando la struttura è: //route/page?queryParameters
Nota
Le route possono essere definite sugli elementi nella gerarchia visiva della shell tramite la Route
proprietà . Tuttavia, se la Route
proprietà non è impostata, ad esempio nell'applicazione Notes, viene generata una route in fase di esecuzione.
Per altre informazioni sullo spostamento nella shell, vedere Xamarin.Forms Navigazione nella shell.
Registrare le route
Per passare a una pagina che non esiste nella gerarchia di oggetti visivi della shell, è necessario che venga registrata prima 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 sul NoteEntryPage
tipo . È quindi possibile passare a questa pagina usando lo spostamento basato 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
Uno stack di spostamento viene creato quando si passa a una pagina che non si trova nella gerarchia visiva della shell.
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()}");
}
}
Questo esempio recupera l'elemento attualmente selezionato in CollectionView
e passa a NoteEntryPage
, con il valore della proprietà dell'oggetto ID
Note
passato come parametro di query alla NoteEntryPage.ItemId
proprietà .
Per ricevere i dati passati, la NoteEntryPage
classe viene decorata con QueryPropertyAttribute
[QueryProperty(nameof(ItemId), nameof(ItemId))]
public partial class NoteEntryPage : ContentPage
{
public string ItemId
{
set
{
LoadNote(value);
}
}
// ...
}
Il primo argomento per l'oggetto QueryPropertyAttribute
specifica che la ItemId
proprietà riceverà i dati passati, con il secondo argomento che specifica l'ID del parametro di query. Pertanto, QueryPropertyAttribute
nell'esempio precedente viene specificato che la ItemId
proprietà riceverà i dati passati nel ItemId
parametro di query dall'URI nella chiamata al GoToAsync
metodo. La ItemId
proprietà chiama quindi il LoadNote
metodo per recuperare la nota dal dispositivo.
Lo spostamento all'indietro viene eseguito specificando ".." come argomento del GoToAsync
metodo :
await Shell.Current.GoToAsync("..");
Per altre informazioni sulla navigazione all'indietro, vedere Spostamento indietro.
Data binding
Il data binding viene usato per semplificare la visualizzazione e l'interazione di un'applicazione Xamarin.Forms con i relativi dati. Stabilisce una connessione tra l'interfaccia utente e l'applicazione sottostante. La classe BindableObject
contiene la maggior parte dell'infrastruttura per supportare il 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 Editor
(oggetto di destinazione) associa comunemente la proprietà Text
a una proprietà string
pubblica in un oggetto di origine. Il diagramma che segue illustra la relazione di associazione:
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 proprietà
BindingContext
dell'oggetto di destinazione deve essere impostata sull'origine. - È necessario stabilire un'associazione tra la destinazione e l'origine. In XAML questo si ottiene usando l'estensione di markup
Binding
.
Nell'applicazione Notes la destinazione del binding è l'Editor
che visualizza una nota, mentre l'istanza di Note
impostata come BindingContext
di NoteEntryPage
è l'origine del binding. Inizialmente, l'oggetto BindingContext
NoteEntryPage
di viene impostato quando viene eseguito il costruttore della pagina:
public NoteEntryPage()
{
// ...
BindingContext = new Note();
}
In questo esempio, la pagina BindingContext
viene impostata su un nuovo Note
oggetto quando NoteEntryPage
viene creato . In questo modo viene gestito lo scenario di aggiunta di una nuova nota all'applicazione.
Inoltre, la pagina BindingContext
può anche essere impostata quando si sposta su NoteEntryPage
, purché sia stata selezionata una nota 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 della pagina, la pagina viene impostata sull'oggetto BindingContext
selezionato Note
dopo che è stato recuperato dal database.
Importante
È possibile impostare individualmente la proprietà BindingContext
di ogni oggetto di destinazione, ma questa operazione non è necessaria. BindingContext
è una proprietà speciale che viene ereditata da tutti gli elementi figlio. Pertanto quando la proprietà BindingContext
in ContentPage
è impostata su un'istanza di Note
, tutti gli elementi figlio di ContentPage
hanno la stessa proprietà BindingContext
e possono eseguire il binding alle proprietà pubbliche dell'oggetto Note
.
L'Editor
in NoteEntryPage
esegue quindi il binding alla proprietà Text
dell'oggetto Note
:
<Editor Placeholder="Enter your note"
Text="{Binding Text}" />
Viene definita un'associazione tra la proprietà Editor.Text
e la proprietà Text
dell'oggetto di origine. Le modifiche apportate nell'Editor
vengono propagate automaticamente all'oggetto Note
. Analogamente, se vengono apportate modifiche alla Note.Text
proprietà , il Xamarin.Forms motore di associazione aggiornerà anche il contenuto di Editor
. Questa funzionalità è detta associazione bidirezionale.
Per altre informazioni sul data binding, vedere Xamarin.Forms Data Binding.
Applicazione stile in corso
Xamarin.Forms le applicazioni contengono spesso più elementi visivi che hanno 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 classe Style
raggruppa una raccolta di valori delle proprietà in un oggetto che può quindi essere applicato a più istanze di un elemento visivo. Gli stili vengono archiviati in una classe ResourceDictionary
a livello di applicazione, di pagina o di visualizzazione. Scegliere dove definire un oggetto Style
ha effetto su dove può essere usato:
- Le istanze di
Style
definite a livello di applicazione possono essere applicate in tutta l'applicazione. - Le istanze di
Style
definite a livello di pagina possono essere applicate alla pagina e agli elementi figlio. - Le istanze di
Style
definite a livello di visualizzazione possono essere applicate alla visualizzazione e agli 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 istanza di Style
contiene una raccolta di uno o più oggetti Setter
e ogni Setter
ha una proprietà Property
e una proprietà 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 qualsiasi istanza di Editor
nella pagina.
Quando si crea una classe Style
, la proprietà TargetType
è sempre obbligatoria.
Nota
Lo stile di un'applicazione Xamarin.Forms viene tradizionalmente eseguito usando gli stili XAML. Tuttavia, Xamarin.Forms supporta anche lo stile degli elementi visivi usando css (Cascading Style Sheets). Per altre informazioni, vedere Applicazione Xamarin.Forms di stili alle app con fogli di stile CSS (Cascading Style Sheets).
Per altre informazioni sugli stili XAML, vedi Applicazione Xamarin.Forms di stili alle app con stili 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 un'applicazione Xamarin.Forms . 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 spostamento delle 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 Xamarin.Forms alle 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 in progetti specifici della piattaforma sottoclassando la
PlatformEffect
classe e vengono utilizzati associandoli a un controllo appropriato Xamarin.Forms . 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 classiRenderer
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).
Collegamenti correlati
- Xamarin.Forms Guscio
- eXtensible Application Markup Language (XAML)
- Data Binding
- Riferimento per i controlli
- Informazioni di riferimento sull'APIXamarin.Forms
Video correlato
Altri video di Xamarin sono disponibili su Channel 9 e YouTube.