Layout associabili in Xamarin.Forms
I layout associabili consentono a qualsiasi classe di layout che deriva dalla Layout<T>
classe di generare il contenuto associandolo a una raccolta di elementi, con l'opzione per impostare l'aspetto di ogni elemento con un oggetto DataTemplate
. I layout associabili vengono forniti dalla BindableLayout
classe , che espone le proprietà associate seguenti:
ItemsSource
: specifica la raccolta diIEnumerable
elementi da visualizzare nel layout.ItemTemplate
: specifica l'oggettoDataTemplate
da applicare a ogni elemento nella raccolta di elementi visualizzati dal layout.ItemTemplateSelector
: specifica l'oggettoDataTemplateSelector
che verrà usato per scegliere unDataTemplate
elemento in fase di esecuzione.
Nota
La ItemTemplate
proprietà ha la precedenza quando vengono impostate entrambe le ItemTemplate
proprietà e ItemTemplateSelector
.
Inoltre, la BindableLayout
classe espone le proprietà associabili seguenti:
EmptyView
: specifica lastring
visualizzazione o che verrà visualizzata quando la proprietà ènull
o quando laItemsSource
raccolta specificata dallaItemsSource
proprietà ènull
o vuota. Il valore predefinito ènull
.EmptyViewTemplate
: specifica l'oggettoDataTemplate
che verrà visualizzato quando la proprietà ènull
o quando laItemsSource
raccolta specificata dallaItemsSource
proprietà ènull
o vuota. Il valore predefinito ènull
.
Nota
La EmptyViewTemplate
proprietà ha la precedenza quando vengono impostate entrambe le EmptyView
proprietà e EmptyViewTemplate
.
Tutte queste proprietà possono essere associate alle AbsoluteLayout
classi , FlexLayout
, Grid
RelativeLayout
, e StackLayout
, che derivano tutte dalla Layout<T>
classe .
La Layout<T>
classe espone una Children
raccolta a cui vengono aggiunti gli elementi figlio di un layout. Quando la BindableLayout.ItemsSource
proprietà è impostata su una raccolta di elementi e associata a una Layout<T>
classe derivata da , ogni elemento dell'insieme viene aggiunto alla raccolta per la Layout<T>.Children
visualizzazione dal layout. La Layout<T>
classe derivata da aggiornerà quindi le visualizzazioni figlio quando cambia la raccolta sottostante. Per altre informazioni sul ciclo di Xamarin.Forms layout, vedere Creazione di un layout personalizzato.
I layout associabili devono essere usati solo quando la raccolta di elementi da visualizzare è ridotta e lo scorrimento e la selezione non sono necessari. Anche se lo scorrimento può essere fornito eseguendo il wrapping di un layout associabile in un oggetto ScrollView
, non è consigliabile perché i layout associabili non dispongono della virtualizzazione dell'interfaccia utente. Quando è necessario lo scorrimento, deve essere usata una visualizzazione scorrevole che include la virtualizzazione dell'interfaccia utente, ad esempio ListView
o CollectionView
. L'impossibilità di osservare questa raccomandazione può causare problemi di prestazioni.
Importante
Sebbene sia tecnicamente possibile associare un layout associabile a qualsiasi classe di layout che deriva dalla Layout<T>
classe , non è sempre pratico farlo, in particolare per le AbsoluteLayout
classi , Grid
e RelativeLayout
. Si consideri, ad esempio, lo scenario di voler visualizzare una raccolta di dati in un Grid
oggetto usando un layout associabile, in cui ogni elemento della raccolta è un oggetto contenente più proprietà. Ogni riga in Grid
deve visualizzare un oggetto dall'insieme, con ogni colonna nella Grid
visualizzazione di una delle proprietà dell'oggetto. Poiché per DataTemplate
il layout associabile può contenere solo un singolo oggetto, è necessario che tale oggetto sia una classe di layout contenente più visualizzazioni che visualizzano ognuna delle proprietà dell'oggetto in una colonna specifica Grid
. Sebbene questo scenario possa essere realizzato con layout associabili, viene generato un elemento padre Grid
contenente un elemento figlio Grid
per ogni elemento nella raccolta associata, che rappresenta un uso estremamente inefficiente e problematico del Grid
layout.
Popolare un layout associabile con i dati
Un layout associabile viene popolato con i dati impostando la relativa ItemsSource
proprietà su qualsiasi raccolta che implementa IEnumerable
e associandola a una Layout<T>
classe derivata da :
<Grid BindableLayout.ItemsSource="{Binding Items}" />
Il codice C# equivalente è il seguente:
IEnumerable<string> items = ...;
var grid = new Grid();
BindableLayout.SetItemsSource(grid, items);
Quando la BindableLayout.ItemsSource
proprietà associata è impostata su un layout, ma la BindableLayout.ItemTemplate
proprietà associata non è impostata, ogni elemento dell'insieme IEnumerable
verrà visualizzato da un Label
oggetto creato dalla BindableLayout
classe .
Definire l'aspetto dell'elemento
L'aspetto di ogni elemento nel layout associabile può essere definito impostando la BindableLayout.ItemTemplate
proprietà associata su :DataTemplate
<StackLayout BindableLayout.ItemsSource="{Binding User.TopFollowers}"
Orientation="Horizontal"
...>
<BindableLayout.ItemTemplate>
<DataTemplate>
<controls:CircleImage Source="{Binding}"
Aspect="AspectFill"
WidthRequest="44"
HeightRequest="44"
... />
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
Il codice C# equivalente è il seguente:
DataTemplate circleImageTemplate = ...;
var stackLayout = new StackLayout();
BindableLayout.SetItemsSource(stackLayout, viewModel.User.TopFollowers);
BindableLayout.SetItemTemplate(stackLayout, circleImageTemplate);
In questo esempio, ogni elemento dell'insieme TopFollowers
verrà visualizzato da una CircleImage
visualizzazione definita in DataTemplate
:
Per altre informazioni sui modelli di dati, vedere Xamarin.Forms Modelli di dati.
Scegliere l'aspetto dell'elemento in fase di esecuzione
L'aspetto di ogni elemento nel layout associabile può essere scelto in fase di esecuzione, in base al valore dell'elemento, impostando la BindableLayout.ItemTemplateSelector
proprietà associata su :DataTemplateSelector
<FlexLayout BindableLayout.ItemsSource="{Binding User.FavoriteTech}"
BindableLayout.ItemTemplateSelector="{StaticResource TechItemTemplateSelector}"
... />
Il codice C# equivalente è il seguente:
DataTemplateSelector dataTemplateSelector = new TechItemTemplateSelector { ... };
var flexLayout = new FlexLayout();
BindableLayout.SetItemsSource(flexLayout, viewModel.User.FavoriteTech);
BindableLayout.SetItemTemplateSelector(flexLayout, dataTemplateSelector);
L'oggetto DataTemplateSelector
usato nell'applicazione di esempio è illustrato nell'esempio seguente:
public class TechItemTemplateSelector : DataTemplateSelector
{
public DataTemplate DefaultTemplate { get; set; }
public DataTemplate XamarinFormsTemplate { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
return (string)item == "Xamarin.Forms" ? XamarinFormsTemplate : DefaultTemplate;
}
}
La TechItemTemplateSelector
classe definisce DefaultTemplate
e XamarinFormsTemplate
DataTemplate
proprietà impostate su modelli di dati diversi. Il OnSelectTemplate
metodo restituisce , XamarinFormsTemplate
che visualizza un elemento in rosso scuro con un cuore accanto a esso, quando l'elemento è uguale a "Xamarin.Forms". Quando l'elemento non è uguale a "Xamarin.Forms", il OnSelectTemplate
metodo restituisce , DefaultTemplate
che visualizza un elemento usando il colore predefinito di un oggetto Label
:
Per altre informazioni sui selettori di modelli di dati, vedere Creazione di un Xamarin.Forms dataTemplateSelector.
Visualizzare una stringa quando i dati non sono disponibili
La EmptyView
proprietà può essere impostata su una stringa, che verrà visualizzata da un Label
oggetto quando la proprietà è null
o quando l'insieme ItemsSource
ItemsSource
specificato dalla proprietà è null
o vuoto. Il codice XAML seguente illustra un esempio di questo scenario:
<StackLayout BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}"
BindableLayout.EmptyView="No achievements">
...
</StackLayout>
Il risultato è che quando la raccolta associata a dati è null
, viene visualizzata la stringa impostata come valore della EmptyView
proprietà:
Visualizzare le visualizzazioni quando i dati non sono disponibili
La EmptyView
proprietà può essere impostata su una visualizzazione, che verrà visualizzata quando la proprietà è null
o quando l'insieme ItemsSource
ItemsSource
specificato dalla proprietà è null
o vuoto. Può trattarsi di una singola visualizzazione o di una visualizzazione che contiene più visualizzazioni figlio. L'esempio XAML seguente mostra la EmptyView
proprietà impostata su una visualizzazione che contiene più visualizzazioni figlio:
<StackLayout BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}">
<BindableLayout.EmptyView>
<StackLayout>
<Label Text="None."
FontAttributes="Italic"
FontSize="{StaticResource smallTextSize}" />
<Label Text="Try harder and return later?"
FontAttributes="Italic"
FontSize="{StaticResource smallTextSize}" />
</StackLayout>
</BindableLayout.EmptyView>
...
</StackLayout>
Il risultato è che quando la raccolta associata a dati è null
, vengono visualizzate le StackLayout
viste figlio e .
Analogamente, EmptyViewTemplate
può essere impostato su un DataTemplate
oggetto , che verrà visualizzato quando la proprietà è null
o quando l'insieme ItemsSource
specificato dalla ItemsSource
proprietà è null
o vuoto. DataTemplate
può contenere una singola visualizzazione o una vista che contiene più visualizzazioni figlio. Inoltre, l'oggetto BindingContext
EmptyViewTemplate
di verrà ereditato dall'oggetto BindingContext
BindableLayout
di . L'esempio XAML seguente mostra la EmptyViewTemplate
proprietà impostata su un DataTemplate
oggetto contenente una singola visualizzazione:
<StackLayout BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}">
<BindableLayout.EmptyViewTemplate>
<DataTemplate>
<Label Text="{Binding Source={x:Reference usernameLabel}, Path=Text, StringFormat='{0} has no achievements.'}" />
</DataTemplate>
</BindableLayout.EmptyViewTemplate>
...
</StackLayout>
Il risultato è che quando la raccolta associata a dati è null
, viene visualizzato l'oggetto Label
DataTemplate
in :
Nota
La EmptyViewTemplate
proprietà non può essere impostata tramite .DataTemplateSelector
Scegliere un controllo EmptyView in fase di esecuzione
Le viste che verranno visualizzate come un EmptyView
oggetto quando i dati non sono disponibili, possono essere definite come ContentView
oggetti in un oggetto ResourceDictionary
. La EmptyView
proprietà può quindi essere impostata su un oggetto specifico ContentView
, in base a una logica di business in fase di esecuzione. Il codice XAML seguente illustra un esempio di questo scenario:
<ContentPage ...>
<ContentPage.Resources>
...
<ContentView x:Key="BasicEmptyView">
<StackLayout>
<Label Text="No achievements."
FontSize="14" />
</StackLayout>
</ContentView>
<ContentView x:Key="AdvancedEmptyView">
<StackLayout>
<Label Text="None."
FontAttributes="Italic"
FontSize="14" />
<Label Text="Try harder and return later?"
FontAttributes="Italic"
FontSize="14" />
</StackLayout>
</ContentView>
</ContentPage.Resources>
<StackLayout>
...
<Switch Toggled="OnEmptyViewSwitchToggled" />
<StackLayout x:Name="stackLayout"
BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}">
...
</StackLayout>
</StackLayout>
</ContentPage>
Il codice XAML definisce due ContentView
oggetti a livello ResourceDictionary
di pagina, con l'oggetto che controlla l'oggetto Switch
ContentView
che verrà impostato come valore della EmptyView
proprietà. Quando l'oggetto Switch
viene attivato o disattivato, il OnEmptyViewSwitchToggled
gestore eventi esegue il ToggleEmptyView
metodo :
void ToggleEmptyView(bool isToggled)
{
object view = isToggled ? Resources["BasicEmptyView"] : Resources["AdvancedEmptyView"];
BindableLayout.SetEmptyView(stackLayout, view);
}
Il ToggleEmptyView
metodo imposta la EmptyView
proprietà dell'oggetto stackLayout
su uno dei due ContentView
oggetti archiviati in ResourceDictionary
, in base al valore della Switch.IsToggled
proprietà . Quindi, quando la raccolta associata a dati è null
, viene visualizzato il ContentView
set di oggetti come EmptyView
proprietà :