Controlli come Page
e View
forniscono proprietà per definirne l’aspetto, la forma e il comportamento all’interno del’app. In particolare, l’aspetto di un controllo può essere gestito attraverso la realizzazione di stili o, più semplicemente, tramite dei template basilari per l’app. Ciononostante, questo approccio non offre una netta separazione tra l’aspetto della pagina e il suo contenuto.
Dalla versione 2.0, Xamarin ha introdotto il componente ControlTemplate
, che offre una netta separazione tra l’aspetto e il contenuto di una Page
o di una View
, permettendo allo sviluppatore di concentrarsi esclusivamente sull’aspetto dei controlli.
Un ControlTemplate
può essere applicato ai seguenti tipi di View
e Page
impostando l’omonima proprietà:
ContentPage
ContentView
TemplatedPage
TemplatedView
dove la TemplatedPage
è la classe base per le ContentPage
e mostra il contenuto a schermo intero impiegando un ControlTemplate
, mentre la TemplatedView
è la classe base della ContentView
.
Un ControlTemplate
può essere definito sia in XAML che in C#:
XAML | Viene impiegata la proprietà ResourceDictionary
ControlTemplate
|
---|---|
C# | Viene definita una pagina o una classe, che può essere globalmente acceduta |
Inoltre, è possibile applicare un ControlTemplate
su due livelli:
- page-level
- application-level
La definizione di questi livelli prevede la seguente gerarchia: supponendo di aver definito due differenti ControlTemplate
, uno per ogni livello con il medesimo nome, quello definito per l’application-level viene sostituito dal template per il page-level.
Creazione di un ControlTemplate in XAML
La creazione di un template per l’application-level prevede che la classe App del progetto Portable sia sostituita dalla sua implementazione alternativa basata su XMAL e C#. Ciò rende più semplice la creazione di un nuovo template in XAML. La nuova classe App implementerà nel code-behind la classe Application
per poter utilizzare la proprietà Resources
che conterrà al suo interno il nuovo ControlTemplate
.
Nel codice XAML della classe App
si definirà il seguente codice:
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="HelloXamarin.App">
<Application.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="HeaderFooterTemplate">
...
</ControlTemplate>
</ResourceDictionary>
</Application.Resources>
</Application>
Attraverso la proprietà Resources
Application
ResourceDictionary
ResourceDictionary
x:Key
ControlTemplate
Ad esempio, si supponga di voler definire per tutte le pagine una schermata composta da un header ed un footer come nella seguente figura:
Il modo più semplice è per implementare tale layout è definire una Grid
Row
- l’header composto da una
BoxView
Image
Label
- un
ContentPresenter
- il footer composto da uno
StackLayout
Label
BoxView
Nel codice XAML si avrà:
<ControlTemplate x:Key="HeaderFooterTemplate">
<Grid BackgroundColor="#003366">
<Grid.RowDefinitions>
<RowDefinition Height="0.1*"/>
<RowDefinition Height="0.85*" />
<RowDefinition Height="0.05*" />
</Grid.RowDefinitions>
<BoxView Grid.ColumnSpan="2" Color="#c7c9cc" />
<Image Grid.Column="1" VerticalOptions="CenterAndExpand" HorizontalOptions="Center">
<Image.Source>
<OnPlatform x:TypeArguments="ImageSource"
iOS="logo.png"
Android="logo.png"
WinPhone="Images/logo.png" />
</Image.Source>
</Image>
<Label Grid.Column="0" Text="Header!!!" TextColor="Black" FontSize="22" VerticalOptions="Center" />
<ContentPresenter Grid.Row="1" Grid.ColumnSpan="2" />
<StackLayout Grid.Row="2" Grid.ColumnSpan="2" BackgroundColor="#c7c9cc">
<Label Text="Footer here!" TextColor="Black" FontSize="18" VerticalOptions="CenterAndExpand" HorizontalOptions="Center"/>
</StackLayout>
</Grid>
</ControlTemplate>
Per impostare il ControlTemplate
in una pagina dell’applicazione, basterà richiamare l’omonima proprietà. Ad esempio, una volta creata la pagina CTApplicationLevel, nel codice XAML si avrà:
<ContentPage ControlTemplate="{StaticResource HeaderFooterTemplate}">
<StackLayout VerticalOptions="CenterAndExpand">
<Label Text="||| Page content |||" TextColor="Black" FontSize="25" HorizontalOptions="Center" />
</StackLayout>
</ContentPage>
Eseguendo quindi l’app sui tre OS di interesse si otterrà il risultato in figura.
Se per una specifica pagina si volesse impiegare un template differente, ad esempio con colori e posizioni degli elementi invertiti, si potrà definrie un ControlTemplate
CTPageLevel
<ContentPage.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="HeaderFooterTemplate">
<Grid BackgroundColor="#003366">
. . .
</Grid>
</ControlTemplate>
</ResourceDictionary>
</ContentPage.Resources>
Analogamente a quanto fatto per la nuova classe App
Resources
ContentPage
ResourceDictionary
application-level