Xamarin.Forms CollectionView EmptyView
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 tipoobject
, a cadeia de caracteres, associação ou exibição que será exibida quando a propriedadeItemsSource
fornull
ou quando a coleção especificada pela propriedadeItemsSource
fornull
ou estiver vazia. O valor padrão énull
.EmptyViewTemplate
, do tipoDataTemplate
, o modelo a ser usado para formatar oEmptyView
especificado. O valor padrão énull
.
Essas propriedades são apoiadas por objetos BindableProperty
, o que significa que as propriedades podem ser alvos de vinculações de dados.
Os principais cenários de uso para a definição da propriedade EmptyView
são a exibição de comentários do usuário quando uma operação de filtragem em um CollectionView
não produz dados e a exibição de comentários do usuário enquanto os dados estão sendo recuperados de um serviço Web.
Observação
A propriedade EmptyView
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 propriedade EmptyView
pode ser definida como uma cadeia de caracteres, que será exibida quando a propriedade ItemsSource
for null
ou quando a coleção especificada pela propriedade ItemsSource
for null
ou estiver 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 vinculada aos dados é null
, a cadeia de caracteres definida como o valor da propriedade EmptyView
é exibida:
Visualizar exibições quando os dados não estiverem disponíveis
A propriedade EmptyView
pode ser definida como um modo de exibição, que será exibido quando a propriedade ItemsSource
for null
ou quando a coleção especificada pela propriedade ItemsSource
fornull
ou vazia. Pode ser uma exibição única ou uma exibição que contém várias exibições filho. O exemplo XAML a seguir mostra a propriedade EmptyView
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 um 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 o layout. Portanto, para posicionar as exibições que compõem seu 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 pelo termo de pesquisa armazenado na propriedade SearchBar.Text
. Se a operação de filtragem não gerar dados, será exibido o StackLayout
definido como o valor da propriedade EmptyView
:
Exibir um tipo personalizado com modelo quando os dados não estão disponíveis
A propriedade EmptyView
pode ser definida como um tipo personalizado, cujo modelo é exibido quando a propriedade ItemsSource
é null
ou quando a coleção especificada pela propriedade ItemsSource
é null
ou está vazia. A propriedade EmptyViewTemplate
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 tipo FilterData
define uma propriedade Filter
e um BindableProperty
correspondente:
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 propriedade EmptyView
é definida como um objeto FilterData
, e os dados da propriedade Filter
são vinculados à propriedade SearchBar.Text
. Quando o SearchBar
executa o FilterCommand
, a coleção exibida pelo CollectionView
é filtrada pelo termo de pesquisa armazenado na propriedade Filter
. Se a operação de filtragem não gerar dados, será exibido o Label
definido em DataTemplate
, que é definido como o valor da propriedade EmptyViewTemplate
:
Observação
Ao exibir um tipo personalizado modelado quando os dados não estão disponíveis, a propriedade EmptyViewTemplate
pode ser configurada para uma exibição que contém várias exibições filho.
Escolher um EmptyView em tempo de execução
Exibições que serão exibidas como um EmptyView
quando os dados não estiverem disponíveis podem ser definidas como objetos ContentView
em um ResourceDictionary
. A propriedade EmptyView
pode ser definida como uma ContentView
específica, com base em alguma lógica de negócios, em tempo de execução. 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 objetos ContentView
no nível da página ResourceDictionary
, com o objeto Switch
controlando qual objeto ContentView
será definido como o valor da propriedade EmptyView
. Quando o Switch
é alternado, o manipulador de eventos OnEmptyViewSwitchToggled
executa o método ToggleEmptyView
:
void ToggleEmptyView(bool isToggled)
{
collectionView.EmptyView = isToggled ? Resources["BasicEmptyView"] : Resources["AdvancedEmptyView"];
}
O método ToggleEmptyView
define a propriedade EmptyView
do objeto collectionView
como um dos dois objetos ContentView
armazenados no ResourceDictionary
, com base no valor da propriedade Switch.IsToggled
. Quando o SearchBar
executa o FilterCommand
, a coleção exibida pelo CollectionView
é filtrada pelo termo de pesquisa armazenado na propriedade SearchBar.Text
. Se a operação de filtragem não gerar dados, será exibido o objeto ContentView
definido como a propriedade EmptyView
:
Para obter mais informações sobre dicionários de recursos, consulte Xamarin.Forms Dicionários de recursos.
Escolha um EmptyViewTemplate no runtime
A aparência do EmptyView
pode ser escolhida no runtime, com base em seu valor, definindo a propriedade CollectionView.EmptyViewTemplate
como um objeto 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>
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 propriedade EmptyView
é definida como a propriedade SearchBar.Text
e a propriedade EmptyViewTemplate
é definida como um objeto SearchTermDataTemplateSelector
.
Quando o SearchBar
executa o FilterCommand
, a coleção exibida pelo CollectionView
é filtrada pelo termo de pesquisa armazenado na propriedade SearchBar.Text
. Se a operação de filtragem não gerar dados, o DataTemplate
escolhido pelo objeto SearchTermDataTemplateSelector
será definido como a propriedade EmptyViewTemplate
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 classe SearchTermTemplateSelector
define as propriedades DefaultTemplate
e OtherTemplate
DataTemplate
que são definidas para modelos de dados diferentes. A substituição OnSelectTemplate
retorna DefaultTemplate
, que exibe uma mensagem para o usuário quando a consulta de pesquisa não for igual a "xamarin". Quando a consulta de pesquisa for igual a "xamarin", a substituição OnSelectTemplate
retornará OtherTemplate
, que exibirá uma mensagem básica para o usuário:
Para obter mais informações sobre seletores de modelo de dados, consulte Criar um Xamarin.Forms DataTemplateSelector.