Layout associabili in Xamarin.Forms

Scaricare l'esempio Scaricare l'esempio

I layout associabili consentono a qualsiasi classe di layout che deriva dalla classe di generare il contenuto tramite l'associazione a una raccolta di elementi, con la possibilità di impostare l'aspetto di ogni Layout<T> elemento con un oggetto DataTemplate . I layout associabili vengono forniti dalla BindableLayout classe , che espone le proprietà associate seguenti:

  • ItemsSource : specifica la raccolta IEnumerable di elementi che devono essere visualizzati dal layout.
  • ItemTemplate : specifica DataTemplate l'oggetto da applicare a ogni elemento nella raccolta di elementi visualizzati dal layout.
  • ItemTemplateSelector : specifica DataTemplateSelector l'oggetto che verrà utilizzato per scegliere un oggetto DataTemplate per un elemento in fase di esecuzione.

Nota

La ItemTemplate proprietà ha la precedenza quando vengono impostate ItemTemplateItemTemplateSelector entrambe le proprietà e .

Inoltre, la BindableLayout classe espone le proprietà associabili seguenti:

  • EmptyView : specifica la visualizzazione o che verrà visualizzata quando la proprietà è o quando la string raccolta specificata dalla proprietà è o ItemsSourcenullItemsSourcenull vuota. Il valore predefinito è null.
  • EmptyViewTemplate : specifica l'oggetto che verrà visualizzato quando la proprietà è o quando la DataTemplate raccolta specificata dalla proprietà è o ItemsSourcenullItemsSourcenull vuota. Il valore predefinito è null.

Nota

La EmptyViewTemplate proprietà ha la precedenza quando vengono impostate EmptyViewEmptyViewTemplate entrambe le proprietà e .

Tutte queste proprietà possono essere associate alle classi AbsoluteLayout , , , e , che FlexLayoutGridRelativeLayoutStackLayout derivano tutte dalla classe Layout<T> .

La Layout<T> classe espone una raccolta Xamarin_Forms Layout<T> _Layout_1_Children" data-linktype="absolute-path">, a cui vengono aggiunti gli elementi figlio di Children un layout. Quando la proprietà è impostata su una raccolta di elementi e associata a una classe derivata da , ogni elemento della raccolta viene aggiunto alla raccolta per la visualizzazione BinableLayout.ItemsSourceLayout<T> da parte del Layout<T>.Children layout. La Layout<T> classe derivata da aggiornerà quindi le visualizzazioni figlio quando la raccolta sottostante viene modificata. Per altre informazioni sul ciclo Xamarin.Forms di layout, vedere Xamarin.Forms

I layout associabili devono essere usati solo quando la raccolta di elementi da visualizzare è piccola e lo scorrimento e la selezione non sono necessari. Anche se lo scorrimento può essere fornito tramite il wrapping di un layout associabile in un oggetto , questa operazione non è consigliata perché i layout associabili non ScrollView dispongono della virtualizzazione dell'interfaccia utente. Quando lo scorrimento è obbligatorio, è necessario usare una visualizzazione scorrevole che include la virtualizzazione dell'interfaccia utente, ad esempio ListViewCollectionView o . Il mancato rispetto di questa raccomandazione può causare problemi di prestazioni.

Importante

Sebbene sia tecnicamente possibile associare un layout associabile a qualsiasi classe di layout che deriva dalla classe , non è sempre pratico farlo, in particolare per le classi Layout<T>AbsoluteLayout , e GridRelativeLayout . Si consideri, ad esempio, lo scenario in cui si desidera visualizzare una raccolta di dati in un oggetto usando un layout associabile, in cui ogni elemento della raccolta è un oggetto contenente Grid più proprietà. In ogni riga dell'oggetto deve essere visualizzato un oggetto della raccolta , con ogni colonna nell'oggetto che visualizza GridGrid una delle proprietà dell'oggetto. Poiché per il layout associabile può contenere solo un singolo oggetto, è necessario che l'oggetto sia una classe di layout contenente più visualizzazioni, ognuna delle quali visualizza una delle proprietà DataTemplate dell'oggetto in una colonna Grid specifica. Anche se questo scenario può essere utilizzato con layout associabili, viene restituito un elemento padre contenente un elemento figlio per ogni elemento nella raccolta associata, che rappresenta un uso estremamente inefficiente e GridGrid problematico del Grid layout.

Popolare un layout associabile con dati

Un layout associabile viene popolato con i dati impostandone la proprietà su qualsiasi raccolta che implementa e associando il layout ItemsSource a una classe derivata da IEnumerableLayout<T> :

<Grid BindableLayout.ItemsSource="{Binding Items}" />

Il codice C# equivalente è il seguente:

IEnumerable<string> items = ...;
var grid = new Grid();
BindableLayout.SetItemsSource(grid, items);

Quando la proprietà associata è impostata su un layout, ma la proprietà associata non è impostata, ogni elemento della raccolta verrà visualizzato da un oggetto creato BindableLayout.ItemsSourceBindableLayout.ItemTemplate dalla classe IEnumerableLabelBindableLayout .

Definire l'aspetto degli elementi

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 della TopFollowers raccolta verrà visualizzato da una visualizzazione definita in CircleImageDataTemplate :

Layout associabile con unlayout DataTemplate con un modello di dati

Per altre informazioni sui modelli di dati, vedere Xamarin.Forms Data Templates .

Scegliere l'aspetto degli elementi 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);

DataTemplateSelectorL'oggetto 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 le proprietà e impostate su modelli di dati DefaultTemplateXamarinFormsTemplateDataTemplate diversi. Il metodo restituisce , che visualizza un elemento in rosso scuro con un centro accanto, quando OnSelectTemplate l'elemento è uguale a " XamarinFormsTemplateXamarin.Forms ". Quando l'elemento non è uguale a " ", il metodo restituisce , che visualizza un elemento usando Xamarin.Forms il colore predefinito di OnSelectTemplateDefaultTemplateLabel :

Layout associabile con un layout associabile DataTemplateSelector

Per altre informazioni sui selettori dei modelli di dati, vedere Creating a Xamarin.Forms DataTemplateSelector .

Visualizzare una stringa quando i dati non sono disponibili

La proprietà può essere impostata su una stringa, che verrà visualizzata da un oggetto quando la proprietà è o quando la raccolta specificata dalla proprietà EmptyViewLabel è o ItemsSourcenullItemsSourcenull vuota. 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 è , viene visualizzata la null stringa impostata come valore EmptyView della proprietà :

Screenshot di una visualizzazione vuota della stringa di layout associabilein iOS e AndroidVisualizzazione vuota della stringa di layout

Visualizzare le visualizzazioni quando i dati non sono disponibili

La proprietà può essere impostata su una visualizzazione, che verrà visualizzata quando la proprietà è o quando la raccolta specificata dalla EmptyViewItemsSource proprietà è o nullItemsSourcenull vuota. Può trattarsi di una singola visualizzazione o di una visualizzazione che contiene più visualizzazioni figlio. L'esempio XAML seguente mostra EmptyView la 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 è , vengono visualizzati l'oggetto e le nullStackLayout relative visualizzazioni figlio.

Screenshot di una visualizzazione vuota con layout associabile con più visualizzazioni, nella visualizzazione vuotaScreenshot of a bindable layout empty view with multiple views, on iOS and Androiddel layoute Android

Analogamente, può essere impostato su , che verrà visualizzato quando la proprietà è o quando la raccolta specificata dalla EmptyViewTemplateDataTemplate proprietà è o ItemsSourcenullItemsSourcenull vuota. può DataTemplate contenere una singola visualizzazione o una visualizzazione che contiene più visualizzazioni figlio. Inoltre, BindingContext l'oggetto EmptyViewTemplate di verrà ereditato da di BindingContextBindableLayout . Nell'esempio XAML seguente viene EmptyViewTemplate illustrata la proprietà impostata su DataTemplate un oggetto che contiene 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 LabelDataTemplate l'oggetto in :

Screenshot di un modello di visualizzazione vuota con layout associabile, iniOS e AndroidModello di visualizzazione vuota

Nota

La EmptyViewTemplate proprietà non può essere impostata tramite DataTemplateSelector .

Scegliere un oggetto EmptyView in fase di esecuzione

Le visualizzazioni che verranno visualizzate come quando i dati non sono disponibili possono essere definite EmptyView come oggetti in un oggetto ContentViewResourceDictionary . La EmptyView proprietà può quindi essere impostata su un oggetto ContentView specifico, 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 oggetti nell'oggetto a livello di pagina, con l'oggetto che controlla ContentView quale oggetto verrà impostato come valore della proprietà ResourceDictionarySwitchContentViewEmptyView . Quando Switch l'oggetto è attivato o disattivato, OnEmptyViewSwitchToggled il gestore eventi esegue il metodo ToggleEmptyView :

void ToggleEmptyView(bool isToggled)
{
    object view = isToggled ? Resources["BasicEmptyView"] : Resources["AdvancedEmptyView"];
    BindableLayout.SetEmptyView(stackLayout, view);
}

Il metodo imposta la proprietà dell'oggetto su uno dei due oggetti archiviati in , in base al valore della proprietà Xamarin_Forms ToggleEmptyViewEmptyViewstackLayoutContentViewResourceDictionaryToggleEmptyView _Switch_IsToggled" data-linktype="absolute-path">. Switch.IsToggled Quindi, quando la raccolta associata a dati è , viene visualizzato nullContentView l'oggetto impostato EmptyView come proprietà :

del layout associabile Screenshot della scelta della visualizzazione vuota in fase di esecuzione, iniOS e AndroidScelta del runtime di visualizzazione vuota per il layout