Xamarin.Forms CollectionView EmptyView

Baixar exemplo Baixar o exemplo

CollectionView define as seguintes propriedades que podem ser usadas para fornecer comentários do usuário quando não há dados a serem exibidos:

  • EmptyView, do tipo object, a cadeia de caracteres, a associação ou a exibição que será exibida quando a ItemsSource propriedade for nullou quando a coleção especificada pela ItemsSource propriedade estiver null ou vazia. O valor padrão é null.
  • EmptyViewTemplate, do tipo DataTemplate, o modelo a ser usado para formatar o especificado EmptyView. O valor padrão é null.

Essas propriedades são apoiadas por BindableProperty objetos , o que significa que as propriedades podem ser destinos de associações de dados.

Os cenários de uso main para definir a EmptyView propriedade são exibir comentários do usuário quando uma operação de filtragem em um CollectionView não gera dados e exibir comentários do usuário enquanto os dados estão sendo recuperados de um serviço Web.

Observação

A EmptyView propriedade pode ser definida como uma exibição que inclui conteúdo interativo, se necessário.

Para obter mais informações sobre modelos de dados, consulte Xamarin.Forms Modelos de dados.

Exibir uma cadeia de caracteres quando os dados não estiverem disponíveis

A EmptyView propriedade pode ser definida como uma cadeia de caracteres, que será exibida quando a ItemsSource propriedade for nullou quando a coleção especificada pela ItemsSource propriedade estiver null ou vazia. O XAML a seguir mostra um exemplo desse cenário:

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

Este é o código C# equivalente:

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

O resultado é que, como a coleção associada a dados é null, a cadeia de caracteres definida como o valor da EmptyView propriedade é exibida:

exibição vazia de texto Captura de tela de uma lista vertical CollectionView com um modo de exibição vazio de texto, na lista vertical CollectionView do iOS e android

Exibir exibições quando os dados não estiverem disponíveis

A EmptyView propriedade pode ser definida como uma exibição, que será exibida quando a ItemsSource propriedade for nullou quando a coleção especificada pela ItemsSource propriedade estiver null ou vazia. Pode ser uma única exibição ou uma exibição que contém várias exibições filho. O exemplo XAML a seguir mostra a EmptyView propriedade definida como uma exibição que contém várias exibições filho:

<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>

Neste exemplo, o que parece ser uma redundante ContentView foi adicionado como o elemento raiz do EmptyView. Isso ocorre porque, internamente, o EmptyView é adicionado a um contêiner nativo que não fornece nenhum contexto para Xamarin.Forms layout. Portanto, para posicionar os modos de exibição que compõem o EmptyView, você deve adicionar um layout raiz, cujo filho é um layout que pode se posicionar dentro do layout raiz.

Este é o código C# equivalente:

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");

Quando o SearchBar executa o FilterCommand, a coleção exibida pelo CollectionView é filtrada para o termo de pesquisa armazenado na SearchBar.Text propriedade . Se a operação de filtragem não produzir dados, o StackLayout conjunto como o valor da EmptyView propriedade será exibido:

Captura de tela de uma lista vertical CollectionView com exibição vazia personalizada, na lista vertical collectionView do iOS e Android

Exibir um tipo personalizado com modelo quando os dados não estiverem disponíveis

A EmptyView propriedade pode ser definida como um tipo personalizado, cujo modelo é exibido quando a ItemsSource propriedade é nullou quando a coleção especificada pela ItemsSource propriedade é null ou vazia. A EmptyViewTemplate propriedade pode ser definida como um DataTemplate que define a aparência do EmptyView. O XAML a seguir mostra um exemplo desse cenário:

<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>

Este é o código C# equivalente:

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

O FilterData tipo define uma Filter propriedade e um correspondente BindableProperty:

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); }
    }
}

A EmptyView propriedade é definida como um FilterData objeto e os dados da Filter propriedade são associados à SearchBar.Text propriedade . Quando o SearchBar executa o FilterCommand, a coleção exibida pelo CollectionView é filtrada para o termo de pesquisa armazenado na Filter propriedade . Se a operação de filtragem não produzir dados, o Label definido no DataTemplate, definido como o valor da EmptyViewTemplate propriedade, será exibido:

Captura de tela de uma lista vertical CollectionView com um modelo de exibição vazio, na lista vertical CollectionView do iOS e android

Observação

Ao exibir um tipo personalizado com modelo quando os dados não estão disponíveis, a EmptyViewTemplate propriedade pode ser definida como uma exibição que contém várias exibições filho.

Escolher um EmptyView em runtime

Exibições que serão exibidas como um EmptyView quando os dados não estiverem disponíveis podem ser definidas como ContentView objetos em um ResourceDictionary. Em EmptyView seguida, a propriedade pode ser definida como um específico ContentView, com base em alguma lógica de negócios, em runtime. O XAML a seguir mostra um exemplo desse cenário:

<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>

Esse XAML define dois ContentView objetos no nível ResourceDictionaryda página, com o Switch objeto controlando qual ContentView objeto será definido como o valor da EmptyView propriedade. Quando o Switch é alternado, o OnEmptyViewSwitchToggled manipulador de eventos executa o ToggleEmptyView método :

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

O ToggleEmptyView método define a EmptyView propriedade do collectionView objeto como um dos dois ContentView objetos armazenados no ResourceDictionary, com base no valor da Switch.IsToggled propriedade . Quando o SearchBar executa o FilterCommand, a coleção exibida pelo CollectionView é filtrada para o termo de pesquisa armazenado na SearchBar.Text propriedade . Se a operação de filtragem não produzir dados, o ContentView objeto definido como a EmptyView propriedade será exibido:

Captura de tela de uma lista vertical CollectionView com exibições vazias trocadas, na lista vertical CollectionView do iOS e Android

Para obter mais informações sobre dicionários de recursos, consulte Xamarin.Forms Dicionários de recursos.

Escolher um EmptyViewTemplate em runtime

A aparência do EmptyView pode ser escolhida em runtime, com base em seu valor, definindo a CollectionView.EmptyViewTemplate propriedade como um DataTemplateSelector objeto :

<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>

Este é o código C# equivalente:

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

A EmptyView propriedade é definida como a SearchBar.Text propriedade e a EmptyViewTemplate propriedade é definida como um SearchTermDataTemplateSelector objeto .

Quando o SearchBar executa o FilterCommand, a coleção exibida pelo CollectionView é filtrada para o termo de pesquisa armazenado na SearchBar.Text propriedade . Se a operação de filtragem não produzir dados, o DataTemplate escolhido pelo SearchTermDataTemplateSelector objeto será definido como a EmptyViewTemplate propriedade e exibido.

O exemplo a seguir mostra a 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;
    }
}

A SearchTermTemplateSelector classe define e OtherTemplateDataTemplate as propriedades definidas DefaultTemplate como modelos de dados diferentes. A OnSelectTemplate substituição retorna DefaultTemplate, que exibe uma mensagem para o usuário, quando a consulta de pesquisa não é igual a "xamarin". Quando a consulta de pesquisa é igual a "xamarin", a OnSelectTemplate substituição retorna OtherTemplate, que exibe uma mensagem básica para o usuário:

captura de tela de uma seleção de modelo de exibição vazia do runtime CollectionView, na seleção de modelo de exibição vazia do iOS e do Android

Para obter mais informações sobre seletores de modelo de dados, consulte Criar um Xamarin.Forms DataTemplateSelector.