Rozložení s možností vazby v Xamarin.Forms

Download Sample Stažení ukázky

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 kolekci IEnumerable položek, které se mají zobrazit rozložením.
  • ItemTemplate – určuje, že DataTemplate se má použít pro každou položku v kolekci položek zobrazených rozložením.
  • ItemTemplateSelector – určuje DataTemplateSelector , že se použije k výběru DataTemplate 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čuje string nebo zobrazení, které se zobrazí, když ItemsSource je nullvlastnost , nebo když kolekce určená ItemsSource vlastností je null nebo je prázdná. Výchozí hodnota je null.
  • EmptyViewTemplate – určuje DataTemplate , že se zobrazí, když ItemsSource je nullvlastnost , nebo když kolekce určená ItemsSource vlastností je null nebo je prázdná. Výchozí hodnota je null.

Poznámka:

Vlastnost EmptyViewTemplate má přednost, když jsou nastaveny EmptyView obě vlastnosti EmptyViewTemplate .

Všechny tyto vlastnosti mohou být připojeny AbsoluteLayoutk , , FlexLayoutGrid, RelativeLayouta 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, Grida 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á LabelBindableLayout 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

Bindable layout with a 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 XamarinFormsTemplateDataTemplate 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í DefaultTemplatemetoda , která zobrazí položku pomocí výchozí barvy Label:

Bindable layout with a DataTemplateSelector

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 nullvlastnost , 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 nullkolekce vázaná na data , řetězec nastavený jako EmptyView hodnota vlastnosti se zobrazí:

Screenshot of a bindable layout string empty view, on iOS and Android

Zobrazení, když data nejsou k dispozici

Vlastnost EmptyView lze nastavit na zobrazení, které se zobrazí, když ItemsSource je nullvlastnost , 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 nullkolekce svázaná s daty , StackLayout zobrazí se podřízená zobrazení.

Screenshot of a bindable layout empty view with multiple views, on iOS and Android

EmptyViewTemplate Podobně lze nastavit na DataTemplatehodnotu , která se zobrazí, když ItemsSource je nullvlastnost , 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 BindingContextBindableLayout. 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 nullsvázaná kolekce dat , zobrazí se Label v objektu DataTemplate :

Screenshot of a bindable layout empty view template, on iOS and Android

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 ResourceDictionarystrá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 ResourceDictionaryzávislosti na hodnotě Switch.IsToggled vlastnosti. Když je nullpak kolekce vázaná na data , ContentView objekt nastavený jako EmptyView vlastnost se zobrazí:

Screenshot of empty view choice at runtime, on iOS and Android