Rozložení s možností vazby v Xamarin.Forms
Svázatelné rozložení umožňují, aby všechny třídy rozložení odvozené od Layout<T>
třídy generovaly svůj obsah vazbou na kolekci položek s možností nastavit vzhled každé položky pomocí DataTemplate
. Rozložení s možností vazby jsou poskytována BindableLayout
třídou, která zveřejňuje následující připojené vlastnosti:
ItemsSource
– určuje kolekciIEnumerable
položek, které se mají zobrazit rozložením.ItemTemplate
– určuje, žeDataTemplate
se má použít pro každou položku v kolekci položek zobrazených rozložením.ItemTemplateSelector
– určujeDataTemplateSelector
, že se použije k výběruDataTemplate
položky za běhu.
Poznámka:
Vlastnost ItemTemplate
má přednost, když jsou nastaveny ItemTemplate
obě vlastnosti ItemTemplateSelector
.
Kromě toho BindableLayout
třída zveřejňuje následující vlastnosti bindable:
EmptyView
– určujestring
nebo zobrazení, které se zobrazí, kdyžItemsSource
jenull
vlastnost , nebo když kolekce určenáItemsSource
vlastností jenull
nebo je prázdná. Výchozí hodnota jenull
.EmptyViewTemplate
– určujeDataTemplate
, že se zobrazí, kdyžItemsSource
jenull
vlastnost , nebo když kolekce určenáItemsSource
vlastností jenull
nebo je prázdná. Výchozí hodnota jenull
.
Poznámka:
Vlastnost EmptyViewTemplate
má přednost, když jsou nastaveny EmptyView
obě vlastnosti EmptyViewTemplate
.
Všechny tyto vlastnosti mohou být připojeny AbsoluteLayout
k , , FlexLayout
Grid
, RelativeLayout
a StackLayout
třídy, které jsou odvozeny od Layout<T>
třídy.
Třída Layout<T>
zveřejňuje kolekci, do které jsou přidány Children
podřízené prvky rozložení. BindableLayout.ItemsSource
Pokud je vlastnost nastavena na kolekci položek a připojena k -odvozené Layout<T>
třídě, každá položka v kolekci je přidána do Layout<T>.Children
kolekce pro zobrazení podle rozložení. -odvozená Layout<T>
třída pak aktualizuje své podřízené zobrazení, když se podkladová kolekce změní. Další informace o cyklu rozložení naleznete v Xamarin.Forms tématu Vytvoření vlastního rozložení.
Rozložení s možností vazby by se měla použít jenom v případě, že je kolekce položek, které se mají zobrazit, malá a posouvání a výběr není potřeba. Při posouvání lze poskytnout zabalením rozložení s možností vazby do objektu ScrollView
, nedoporučuje se to, protože vázaná rozložení nemají virtualizaci uživatelského rozhraní. Při vyžadování posouvání by se mělo použít posuvné zobrazení, které zahrnuje virtualizaci uživatelského rozhraní, například ListView
nebo CollectionView
. Pokud toto doporučení nedodržíte, může to vést k problémům s výkonem.
Důležité
I když je technicky možné připojit vázání rozložení k jakékoli třídě rozložení odvozené od Layout<T>
třídy, není vždy praktické to udělat, zejména pro AbsoluteLayout
, Grid
a RelativeLayout
třídy. Představte si například scénář, kdy chcete zobrazit kolekci dat v Grid
rozložení s možností vazby, kde každá položka v kolekci je objekt obsahující více vlastností. Každý řádek v Grid
kolekci by měl zobrazit objekt s každým sloupcem Grid
v zobrazení jedné z vlastností objektu. DataTemplate
Vzhledem k tomu, že rozložení pro vytvoření vazby může obsahovat pouze jeden objekt, je nutné, aby byl objekt třídou rozložení obsahující více zobrazení, která každá zobrazuje jednu z vlastností objektu v určitém Grid
sloupci. I když je možné tento scénář realizovat pomocí rozložení s možností vazby, výsledkem je nadřazený Grid
objekt obsahující podřízenou Grid
položku pro každou položku v vázané kolekci, což je velmi neefektivní a problematické použití Grid
rozložení.
Naplnění svázatelného rozložení dat
Rozložení s možností vazby je naplněno daty nastavením jeho ItemsSource
vlastnosti na libovolnou kolekci, která implementuje IEnumerable
, a připojit ho k -odvozené Layout<T>
třídě:
<Grid BindableLayout.ItemsSource="{Binding Items}" />
Ekvivalentní kód jazyka C# je:
IEnumerable<string> items = ...;
var grid = new Grid();
BindableLayout.SetItemsSource(grid, items);
Pokud je připojená BindableLayout.ItemsSource
vlastnost nastavena v rozložení, ale BindableLayout.ItemTemplate
připojená vlastnost není nastavena, zobrazí se každá položka v IEnumerable
kolekci vytvořená Label
BindableLayout
třídou.
Definování vzhledu položky
Vzhled každé položky v rozložení s možností vazby lze definovat nastavením BindableLayout.ItemTemplate
připojené vlastnosti na 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>
Ekvivalentní kód jazyka C# je:
DataTemplate circleImageTemplate = ...;
var stackLayout = new StackLayout();
BindableLayout.SetItemsSource(stackLayout, viewModel.User.TopFollowers);
BindableLayout.SetItemTemplate(stackLayout, circleImageTemplate);
V tomto příkladu TopFollowers
se každá položka v kolekci zobrazí zobrazením definovaným CircleImage
v :DataTemplate
Další informace o šablonách dat naleznete v tématu Xamarin.Forms Šablony dat.
Volba vzhledu položky za běhu
Vzhled každé položky v rozložení s možností vázání lze zvolit za běhu na základě hodnoty položky nastavením BindableLayout.ItemTemplateSelector
připojené vlastnosti na DataTemplateSelector
:
<FlexLayout BindableLayout.ItemsSource="{Binding User.FavoriteTech}"
BindableLayout.ItemTemplateSelector="{StaticResource TechItemTemplateSelector}"
... />
Ekvivalentní kód jazyka C# je:
DataTemplateSelector dataTemplateSelector = new TechItemTemplateSelector { ... };
var flexLayout = new FlexLayout();
BindableLayout.SetItemsSource(flexLayout, viewModel.User.FavoriteTech);
BindableLayout.SetItemTemplateSelector(flexLayout, dataTemplateSelector);
Použití DataTemplateSelector
v ukázkové aplikaci je znázorněno v následujícím příkladu:
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;
}
}
Třída TechItemTemplateSelector
definuje a XamarinFormsTemplate
DataTemplate
vlastnosti, které jsou nastaveny DefaultTemplate
na různé šablony dat. Metoda OnSelectTemplate
vrátí XamarinFormsTemplate
, který zobrazí položku tmavě červenou se srdcem vedle ní, když je položka rovna "Xamarin.Forms". Pokud položka není rovna "Xamarin.Forms", OnSelectTemplate
vrátí DefaultTemplate
metoda , která zobrazí položku pomocí výchozí barvy Label
:
Další informace o selektorech šablon dat naleznete v tématu Vytvoření objektu Xamarin.Forms DataTemplateSelector.
Zobrazení řetězce, když data nejsou k dispozici
Vlastnost EmptyView
může být nastavena na řetězec, který se zobrazí Label
v případě, že ItemsSource
je null
vlastnost , nebo když kolekce určená ItemsSource
vlastností je null
nebo je prázdná. Následující xaml ukazuje příklad tohoto scénáře:
<StackLayout BindableLayout.ItemsSource="{Binding UserWithoutAchievements.Achievements}"
BindableLayout.EmptyView="No achievements">
...
</StackLayout>
Výsledkem je, že když je null
kolekce vázaná na data , řetězec nastavený jako EmptyView
hodnota vlastnosti se zobrazí:
Zobrazení, když data nejsou k dispozici
Vlastnost EmptyView
lze nastavit na zobrazení, které se zobrazí, když ItemsSource
je null
vlastnost , nebo když kolekce určená ItemsSource
vlastností je null
nebo je prázdná. Může to být jedno zobrazení nebo zobrazení, které obsahuje více podřízených zobrazení. Následující příklad XAML ukazuje EmptyView
vlastnost nastavenou na zobrazení, které obsahuje více podřízených zobrazení:
<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>
Výsledkem je, že když je null
kolekce svázaná s daty , StackLayout
zobrazí se podřízená zobrazení.
EmptyViewTemplate
Podobně lze nastavit na DataTemplate
hodnotu , která se zobrazí, když ItemsSource
je null
vlastnost , nebo když kolekce určená ItemsSource
vlastností je null
nebo je prázdná. Může DataTemplate
obsahovat jedno zobrazení nebo zobrazení, které obsahuje více podřízených zobrazení. Kromě toho BindingContext
bude zděděna EmptyViewTemplate
z BindingContext
BindableLayout
. Následující příklad XAML ukazuje EmptyViewTemplate
vlastnost nastavenou DataTemplate
na, která obsahuje jedno zobrazení:
<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>
Výsledkem je, že když je null
svázaná kolekce dat , zobrazí se Label
v objektu DataTemplate
:
Poznámka:
Vlastnost EmptyViewTemplate
nelze nastavit pomocí parametru DataTemplateSelector
.
Volba prázdného zobrazení za běhu
Zobrazení, která se zobrazí jako EmptyView
při nedostupnosti dat, lze definovat jako ContentView
objekty v objektu ResourceDictionary
. Vlastnost EmptyView
pak může být nastavena na konkrétní ContentView
, na základě určité obchodní logiky za běhu. Následující xaml ukazuje příklad tohoto scénáře:
<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>
XAML definuje dva ContentView
objekty na úrovni ResourceDictionary
stránky s objektem Switch
určujícím, který ContentView
objekt bude nastaven jako EmptyView
hodnota vlastnosti. Při přepnutí OnEmptyViewSwitchToggled
obslužné Switch
rutiny události spustí metoduToggleEmptyView
:
void ToggleEmptyView(bool isToggled)
{
object view = isToggled ? Resources["BasicEmptyView"] : Resources["AdvancedEmptyView"];
BindableLayout.SetEmptyView(stackLayout, view);
}
Metoda ToggleEmptyView
nastaví EmptyView
vlastnost objektu stackLayout
na jeden ze dvou ContentView
objektů uložených v ResourceDictionary
závislosti na hodnotě Switch.IsToggled
vlastnosti. Když je null
pak kolekce vázaná na data , ContentView
objekt nastavený jako EmptyView
vlastnost se zobrazí: