Partager via


Xamarin.Forms CollectionView EmptyView

CollectionView définit les propriétés suivantes qui peuvent être utilisées pour fournir des commentaires utilisateur lorsqu’il n’existe aucune donnée à afficher :

  • EmptyView, de type object, la chaîne, liaison ou affichage qui s’affiche lorsque la propriété ItemsSource est null, ou lorsque la collection spécifiée par la propriété ItemsSource est null ou vide. La valeur par défaut est null.
  • EmptyViewTemplate, de type DataTemplate, le modèle à utiliser pour mettre en forme le EmptyView spécifié. La valeur par défaut est null.

Les propriétés s’appuient sur des objets BindableProperty, ce qui signifie qu’elles peuvent être les cibles de liaisons de données.

Les principaux scénarios d’utilisation de la définition de la propriété EmptyView affichent des commentaires utilisateur lorsqu’une opération de filtrage sur un CollectionView ne génère aucune donnée et affiche les commentaires des utilisateurs pendant que les données sont récupérées à partir d’un service web.

Remarque

La propriété EmptyView peut être définie sur une vue qui inclut du contenu interactif si nécessaire.

Pour plus d’informations sur les modèles de données, consultez Xamarin.Forms Modèles de données.

Afficher une chaîne lorsque les données ne sont pas disponibles

Vous pouvez définir la propriété EmptyView sur une chaîne, celle-ci étant affichée lorsque la propriété ItemsSource est null, ou lorsque la collection spécifiée par la propriété ItemsSource est null ou vide. Le XAML suivant montre un exemple de ce scénario :

<CollectionView ItemsSource="{Binding EmptyMonkeys}"
                EmptyView="No items to display" />

Le code C# équivalent est :

CollectionView collectionView = new CollectionView
{
    EmptyView = "No items to display"
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "EmptyMonkeys");

Ainsi, comme la collection liée aux données est null, la chaîne définie comme valeur de propriété EmptyView est affichée :

Capture d’écran d’une liste verticale CollectionView avec un affichage texte vide, sur iOS et Android

Afficher des vues lorsque les données ne sont pas disponibles

Vous pouvez définir la propriété EmptyView sur une vue, celle-ci étant affichée lorsque la propriété ItemsSource est null ou lorsque la collection spécifiée par la propriété ItemsSource est null ou vide. Il peut s’agir d’une vue unique ou d’une vue contenant plusieurs vues enfants. L’exemple XAML suivant illustre la propriété EmptyView définie sur une vue contenant plusieurs vues enfants :

<StackLayout Margin="20">
    <SearchBar x:Name="searchBar"
               SearchCommand="{Binding FilterCommand}"
               SearchCommandParameter="{Binding Source={x:Reference searchBar}, Path=Text}"
               Placeholder="Filter" />
    <CollectionView ItemsSource="{Binding Monkeys}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                ...
            </DataTemplate>
        </CollectionView.ItemTemplate>
        <CollectionView.EmptyView>
            <ContentView>
                <StackLayout HorizontalOptions="CenterAndExpand"
                             VerticalOptions="CenterAndExpand">
                    <Label Text="No results matched your filter."
                           Margin="10,25,10,10"
                           FontAttributes="Bold"
                           FontSize="18"
                           HorizontalOptions="Fill"
                           HorizontalTextAlignment="Center" />
                    <Label Text="Try a broader filter?"
                           FontAttributes="Italic"
                           FontSize="12"
                           HorizontalOptions="Fill"
                           HorizontalTextAlignment="Center" />
                </StackLayout>
            </ContentView>
        </CollectionView.EmptyView>
    </CollectionView>
</StackLayout>

Dans cet exemple, ce qui ressemble à un redondant ContentView a été ajouté en tant qu’élément racine du EmptyView. Cela est dû au fait que, en interne, il EmptyView est ajouté à un conteneur natif qui ne fournit aucun contexte pour Xamarin.Forms la disposition. Par conséquent, pour positionner les affichages qui composent votre EmptyView, vous devez ajouter une disposition racine, dont l’enfant est une disposition qui peut se positionner dans la disposition racine.

Le code C# équivalent est :

SearchBar searchBar = new SearchBar { ... };
CollectionView collectionView = new CollectionView
{
    EmptyView = new ContentView
    {
        Content = new StackLayout
        {
            Children =
            {
                new Label { Text = "No results matched your filter.", ... },
                new Label { Text = "Try a broader filter?", ... }
            }
        }
    }
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

Lorsque le SearchBar exécute la FilterCommand, la collection affichée par le CollectionView est filtrée pour le terme de recherche stocké dans la propriété SearchBar.Text. Si l’opération de filtrage ne génère aucune donnée, la StackLayout définie comme la valeur de propriété de EmptyView est affichée :

Capture d’écran d’une liste verticale CollectionView avec affichage vide personnalisé, sur iOS et Android

Afficher un type personnalisé basé sur un modèle lorsque les données ne sont pas disponibles

La propriété EmptyView peut être définie sur un type personnalisé, dont le modèle est affiché lorsque la propriété ItemsSource est null, ou lorsque la collection spécifiée par la propriété ItemsSource est null ou vide. Vous pouvez définir la propriété EmptyViewTemplate sur un DataTemplate qui définit l’apparence du EmptyView. Le XAML suivant montre un exemple de ce scénario :

<StackLayout Margin="20">
    <SearchBar x:Name="searchBar"
               SearchCommand="{Binding FilterCommand}"
               SearchCommandParameter="{Binding Source={x:Reference searchBar}, Path=Text}"
               Placeholder="Filter" />
    <CollectionView ItemsSource="{Binding Monkeys}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                ...
            </DataTemplate>
        </CollectionView.ItemTemplate>
        <CollectionView.EmptyView>
            <views:FilterData Filter="{Binding Source={x:Reference searchBar}, Path=Text}" />
        </CollectionView.EmptyView>
        <CollectionView.EmptyViewTemplate>
            <DataTemplate>
                <Label Text="{Binding Filter, StringFormat='Your filter term of {0} did not match any records.'}"
                       Margin="10,25,10,10"
                       FontAttributes="Bold"
                       FontSize="18"
                       HorizontalOptions="Fill"
                       HorizontalTextAlignment="Center" />
            </DataTemplate>
        </CollectionView.EmptyViewTemplate>
    </CollectionView>
</StackLayout>

Le code C# équivalent est :

SearchBar searchBar = new SearchBar { ... };
CollectionView collectionView = new CollectionView
{
    EmptyView = new FilterData { Filter = searchBar.Text },
    EmptyViewTemplate = new DataTemplate(() =>
    {
        return new Label { ... };
    })
};

Le type FilterData définit une propriété Filter et une BindableProperty correspondante :

public class FilterData : BindableObject
{
    public static readonly BindableProperty FilterProperty = BindableProperty.Create(nameof(Filter), typeof(string), typeof(FilterData), null);

    public string Filter
    {
        get { return (string)GetValue(FilterProperty); }
        set { SetValue(FilterProperty, value); }
    }
}

La propriété EmptyView est définie sur un objet FilterData et les données de propriété Filter sont liées à la propriété SearchBar.Text. Lorsque la SearchBar exécute la FilterCommand, la collection affichée par le CollectionView est filtrée pour le terme de recherche stocké dans la propriété Filter. Si l’opération de filtrage ne génère aucune donnée, l’élément Label défini dans le DataTemplate, qui est défini comme la valeur de propriété EmptyViewTemplate, s’affiche :

Capture d’écran d’une liste verticale CollectionView avec un modèle d’affichage vide, sur iOS et Android

Remarque

Lors de l’affichage d’un type personnalisé basé sur un modèle lorsque les données ne sont pas disponibles, la propriété EmptyViewTemplate peut être définie sur un affichage qui contient plusieurs affichages enfants.

Choisir un EmptyView au moment de l’exécution

Les vues affichées comme EmptyView lorsque les données ne sont pas disponibles peuvent être définies en tant qu’objets ContentView dans un ResourceDictionary. Vous pouvez ensuite définir la propriété EmptyView sur un ContentView spécifique, en fonction d’une logique métier, au moment de l’exécution. Le XAML suivant montre un exemple de ce scénario :

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="CollectionViewDemos.Views.EmptyViewSwapPage"
             Title="EmptyView (swap)">
    <ContentPage.Resources>
        <ContentView x:Key="BasicEmptyView">
            <StackLayout>
                <Label Text="No items to display."
                       Margin="10,25,10,10"
                       FontAttributes="Bold"
                       FontSize="18"
                       HorizontalOptions="Fill"
                       HorizontalTextAlignment="Center" />
            </StackLayout>
        </ContentView>
        <ContentView x:Key="AdvancedEmptyView">
            <StackLayout>
                <Label Text="No results matched your filter."
                       Margin="10,25,10,10"
                       FontAttributes="Bold"
                       FontSize="18"
                       HorizontalOptions="Fill"
                       HorizontalTextAlignment="Center" />
                <Label Text="Try a broader filter?"
                       FontAttributes="Italic"
                       FontSize="12"
                       HorizontalOptions="Fill"
                       HorizontalTextAlignment="Center" />
            </StackLayout>
        </ContentView>
    </ContentPage.Resources>

    <StackLayout Margin="20">
        <SearchBar x:Name="searchBar"
                   SearchCommand="{Binding FilterCommand}"
                   SearchCommandParameter="{Binding Source={x:Reference searchBar}, Path=Text}"
                   Placeholder="Filter" />
        <StackLayout Orientation="Horizontal">
            <Label Text="Toggle EmptyViews" />
            <Switch Toggled="OnEmptyViewSwitchToggled" />
        </StackLayout>
        <CollectionView x:Name="collectionView"
                        ItemsSource="{Binding Monkeys}">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    ...
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>
</ContentPage>

Ce XAML définit deux objets ContentView au niveau de la page ResourceDictionary, l’objet Switch contrôlant l’objet ContentView qui sera défini comme la valeur de propriété EmptyView. Lorsque le Switch est basculé, le gestionnaire d’événements OnEmptyViewSwitchToggled exécute la méthode ToggleEmptyView :

void ToggleEmptyView(bool isToggled)
{
    collectionView.EmptyView = isToggled ? Resources["BasicEmptyView"] : Resources["AdvancedEmptyView"];
}

La méthode ToggleEmptyView définit la propriété EmptyView de l’objet collectionView sur l’un des deux objets ContentView stockés dans le ResourceDictionary, en fonction de la valeur de la propriété Switch.IsToggled. Lorsque le SearchBar exécute la FilterCommand, la collection affichée par le CollectionView est filtrée pour le terme de recherche stocké dans la propriété SearchBar.Text. Si l’opération de filtrage ne génère aucune donnée, l’objet ContentView défini comme la propriété EmptyView s’affiche :

Capture d’écran d’une liste verticale CollectionView avec affichages vides échangés, sur iOS et Android

Pour plus d’informations sur les dictionnaires de ressources, consultez Xamarin.Forms Dictionnaires de ressources.

Choisir un EmptyViewTemplate au moment du runtime

Vous pouvez choisir l’apparence du EmptyView au moment du runtime, en fonction de sa valeur, en définissant la propriété CollectionView.EmptyViewTemplate sur un objet DataTemplateSelector :

<ContentPage ...
             xmlns:controls="clr-namespace:CollectionViewDemos.Controls">
    <ContentPage.Resources>
        <DataTemplate x:Key="AdvancedTemplate">
            ...
        </DataTemplate>

        <DataTemplate x:Key="BasicTemplate">
            ...
        </DataTemplate>

        <controls:SearchTermDataTemplateSelector x:Key="SearchSelector"
                                                 DefaultTemplate="{StaticResource AdvancedTemplate}"
                                                 OtherTemplate="{StaticResource BasicTemplate}" />
    </ContentPage.Resources>

    <StackLayout Margin="20">
        <SearchBar x:Name="searchBar"
                   SearchCommand="{Binding FilterCommand}"
                   SearchCommandParameter="{Binding Source={x:Reference searchBar}, Path=Text}"
                   Placeholder="Filter" />
        <CollectionView ItemsSource="{Binding Monkeys}"
                        EmptyView="{Binding Source={x:Reference searchBar}, Path=Text}"
                        EmptyViewTemplate="{StaticResource SearchSelector}" />
    </StackLayout>
</ContentPage>

Le code C# équivalent est :

SearchBar searchBar = new SearchBar { ... };
CollectionView collectionView = new CollectionView
{
    EmptyView = searchBar.Text,
    EmptyViewTemplate = new SearchTermDataTemplateSelector { ... }
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

La propriété EmptyView est définie sur la propriété SearchBar.Text et la propriété EmptyViewTemplate est définie sur un objet SearchTermDataTemplateSelector.

Lorsque le SearchBar exécute la FilterCommand, la collection affichée par le CollectionView est filtrée pour le terme de recherche stocké dans la propriété SearchBar.Text. Si l’opération de filtrage ne génère aucune donnée, le DataTemplate choisi par l’objet SearchTermDataTemplateSelector est défini comme la propriété EmptyViewTemplate et s’affiche.

L’exemple suivant présente la classe SearchTermDataTemplateSelector :

public class SearchTermDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate DefaultTemplate { get; set; }
    public DataTemplate OtherTemplate { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        string query = (string)item;
        return query.ToLower().Equals("xamarin") ? OtherTemplate : DefaultTemplate;
    }
}

La classe SearchTermTemplateSelector définit les propriétés DefaultTemplate et OtherTemplate DataTemplate définies sur différents modèles de données. Le remplacement de OnSelectTemplate retourne DefaultTemplate qui affiche un message à l’utilisateur, lorsque la requête de recherche n’est pas égale à « xamarin ». Lorsque la requête de recherche est égale à « xamarin », le remplacement de OnSelectTemplate retourne OtherTemplate qui affiche un message de base à l’utilisateur :

Capture d’écran d’une sélection de modèle d’affichage vide du runtime CollectionView, sur iOS et Android

Pour plus d’informations sur les sélecteurs de modèles de données, consultez Créer un Xamarin.Forms DataTemplateSelector.