Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
CollectionView de .NET Multi-platform App UI (.NET MAUI) define las siguientes propiedades que se pueden usar para proporcionar comentarios de usuarios cuando no hay datos que mostrar:
EmptyView
, de tipoobject
, la cadena, el enlace o la vista que se mostrarán cuando la propiedadItemsSource
seanull
o cuando la colección especificada por la propiedadItemsSource
seanull
o esté vacía. El valor predeterminado esnull
.EmptyViewTemplate
, de tipo DataTemplate, la plantilla utilizada para dar formato específico aEmptyView
. El valor predeterminado esnull
.
Todas estas propiedades están respaldadas por objetos BindableProperty, lo que significa que las propiedades pueden ser destinos de los enlaces de datos.
Los principales escenarios de uso para establecer la propiedad EmptyView
muestran comentarios de usuario cuando una operación de filtrado de un CollectionView no produce datos y muestra los comentarios de usuario mientras se recuperan datos de un servicio web.
Nota:
La propiedad EmptyView
se puede establecer en una vista que incluya contenido interactivo si es necesario.
Para obtener más información sobre las plantillas de datos, consulta Plantillas de datos.
Mostrar una cadena cuando los datos no están disponibles
La propiedad EmptyView
se puede establecer en una cadena, que se mostrará cuando la propiedad ItemsSource
sea null
, o cuando la colección especificada por la propiedad ItemsSource
sea null
o esté vacía. En el siguiente XAML se muestra un ejemplo de este caso:
<CollectionView ItemsSource="{Binding EmptyMonkeys}"
EmptyView="No items to display" />
El código de C# equivalente es el siguiente:
CollectionView collectionView = new CollectionView
{
EmptyView = "No items to display"
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, static (MonkeysViewModel vm) => vm.EmptyMonkeys);
El resultado es que, dado que la colección enlazada a datos es null
, se muestra el conjunto de cadenas como el valor de propiedad EmptyView
:
Muestra de vistas cuando los datos no están disponibles
La propiedad EmptyView
se puede establecer en una vista, que se mostrará cuando la propiedad ItemsSource
sea null
, o cuando la colección especificada por la propiedad ItemsSource
sea null
o esté vacía. Puede ser una sola vista o una vista que contenga varias vistas secundarias. En el ejemplo XAML siguiente se muestra la propiedad EmptyView
establecida en una vista que contiene varias vistas secundarias:
<Grid Margin="20" RowDefinitions="Auto,*">
<SearchBar x:Name="searchBar"
SearchCommand="{Binding FilterCommand}"
SearchCommandParameter="{Binding x:DataType='SearchBar', Source={x:Reference searchBar}, Path=Text}"
Placeholder="Filter" />
<CollectionView ItemsSource="{Binding Monkeys}"
Grid.Row="1">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:Monkey">
...
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.EmptyView>
<ContentView>
<StackLayout HorizontalOptions="Center"
VerticalOptions="Center">
<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>
</Grid>
En este ejemplo, lo que parece una redundancia se ha agregado como el elemento raíz de EmptyView
. Esto se debe a que, internamente, EmptyView
se agrega a un contenedor nativo que no proporciona ningún contexto para el diseño de .NET MAUI. Por lo tanto, para colocar las vistas que componen EmptyView
, debes agregar un diseño raíz, cuyo elemento secundario es un diseño que puede colocarse dentro del diseño raíz.
El código de C# equivalente es el siguiente:
StackLayout stackLayout = new StackLayout();
stackLayout.Add(new Label { Text = "No results matched your filter.", ... } );
stackLayout.Add(new Label { Text = "Try a broader filter?", ... } );
SearchBar searchBar = new SearchBar { ... };
CollectionView collectionView = new CollectionView
{
EmptyView = new ContentView
{
Content = stackLayout
}
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, static (MonkeysViewModel vm) => vm.Monkeys);
Cuando SearchBar ejecuta FilterCommand
, la colección mostrada por CollectionView se filtra para el término de búsqueda almacenado en la propiedad SearchBar.Text
. Si la operación de filtrado no produce ningún dato, se muestra el conjunto StackLayout establecido como valor de propiedad EmptyView
:
Mostrar un tipo personalizado con plantilla cuando los datos no están disponibles
La propiedad EmptyView
se puede establecer en un tipo personalizado, cuya plantilla se muestra cuando la propiedad ItemsSource
es null
o cuando la colección especificada por la propiedad ItemsSource
es null
o está vacía. La propiedad EmptyViewTemplate
se puede establecer en un DataTemplate que define la apariencia de EmptyView
. En el siguiente XAML se muestra un ejemplo de este caso:
<Grid Margin="20" RowDefinitions="Auto,*">
<SearchBar x:Name="searchBar"
SearchCommand="{Binding FilterCommand}"
SearchCommandParameter="{Binding x:DataType='SearchBar', Source={x:Reference searchBar}, Path=Text}"
Placeholder="Filter" />
<CollectionView ItemsSource="{Binding Monkeys}"
Grid.Row="1">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:Monkey">
...
</DataTemplate>
</CollectionView.ItemTemplate>
<CollectionView.EmptyView>
<views:FilterData x:DataType="SearchBar"
Filter="{Binding Source={x:Reference searchBar}, Path=Text}" />
</CollectionView.EmptyView>
<CollectionView.EmptyViewTemplate>
<DataTemplate>
<Label x:DataType="controls:FilterData"
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>
</Grid>
El código de C# equivalente es el siguiente:
SearchBar searchBar = new SearchBar { ... };
CollectionView collectionView = new CollectionView
{
EmptyView = new FilterData { Filter = searchBar.Text },
EmptyViewTemplate = new DataTemplate(() =>
{
return new Label { ... };
})
};
El tipo FilterData
define una propiedad Filter
y una BindableProperty correspondiente:
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 propiedad EmptyView
se establece en un objeto FilterData
y los datos de propiedad Filter
se enlazan a la propiedad SearchBar.Text
. Cuando SearchBar ejecuta FilterCommand
, la colección mostrada por CollectionView se filtra para el término de búsqueda almacenado en la propiedad Filter
. Si la operación de filtrado no produce ningún dato, se muestra la clase Label definida en DataTemplate que se establece como valor de propiedad EmptyViewTemplate
:
Nota:
Al mostrar un tipo personalizado con plantilla cuando los datos no están disponibles, la propiedad EmptyViewTemplate
se puede establecer en una vista que contenga varias vistas secundarias.
Elección de EmptyView en tiempo de ejecución
Las vistas que se mostrarán como EmptyView
cuando los datos no estén disponibles, se pueden definir como objetos ContentView en un ResourceDictionary. Luego, la propiedad EmptyView
se puede establecer en un elemento ContentView específico, en función de alguna lógica de negocios, en tiempo de ejecución. En el siguiente archivo XAML se muestra un ejemplo de este escenario:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:models="clr-namespace:CollectionViewDemos.Models"
xmlns:viewmodels="clr-namespace:CollectionViewDemos.ViewModels"
x:Class="CollectionViewDemos.Views.EmptyViewSwapPage"
Title="EmptyView (swap)"
x:DataType="viewmodels:MonkeysViewModel">
<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>
<Grid Margin="20" RowDefinitions="Auto, Auto, *">
<SearchBar x:Name="searchBar"
SearchCommand="{Binding FilterCommand}"
SearchCommandParameter="{Binding x:DataType='SearchBar', Source={x:Reference searchBar}, Path=Text}"
Placeholder="Filter" />
<HorizontalStackLayout Grid.Row="1">
<Label Text="Toggle EmptyViews" />
<Switch Toggled="OnEmptyViewSwitchToggled" />
</HorizontalStackLayout>
<CollectionView x:Name="collectionView"
ItemsSource="{Binding Monkeys}"
Grid.Row="2">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="models:Monkey">
...
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</ContentPage>
Este XAML define dos objetos ContentView en el nivel de página ResourceDictionary, con el objeto Switch que controla qué objeto ContentView se establecerá como valor de propiedad EmptyView
. Cuando Switch está activado, el controlador de eventos OnEmptyViewSwitchToggled
ejecuta el método ToggleEmptyView
:
void ToggleEmptyView(bool isToggled)
{
collectionView.EmptyView = isToggled ? Resources["BasicEmptyView"] : Resources["AdvancedEmptyView"];
}
El método ToggleEmptyView
establece la propiedad EmptyView
del objeto CollectionView en uno de los dos objetos ContentView almacenados en ResourceDictionary, en función del valor de la propiedad Switch.IsToggled
. Cuando SearchBar ejecuta FilterCommand
, la colección mostrada por CollectionView se filtra para el término de búsqueda almacenado en la propiedad SearchBar.Text
. Si la operación de filtrado no produce datos, se muestra el objeto ContentView establecido como propiedad EmptyView
:
Para obtener más información sobre los diccionarios de recursos, consulta Diccionarios de recursos.
Elección de EmptyViewTemplate en tiempo de ejecución
La apariencia de EmptyView
se puede elegir en tiempo de ejecución, en función de su valor, estableciendo la propiedad CollectionView.EmptyViewTemplate
en un objeto DataTemplateSelector:
<ContentPage ...
xmlns:controls="clr-namespace:CollectionViewDemos.Controls"
xmlns:viewmodels="clr-namespace:CollectionViewDemos.ViewModels"
x:DataType="viewmodels:MonkeysViewModel">
<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>
<Grid Margin="20" RowDefinitions="Auto,*">
<SearchBar x:Name="searchBar"
SearchCommand="{Binding FilterCommand}"
SearchCommandParameter="{Binding x:DataType='SearchBar', Source={x:Reference searchBar}, Path=Text}"
Placeholder="Filter" />
<CollectionView ItemsSource="{Binding Monkeys}"
EmptyView="{Binding x:DataType='SearchBar', Source={x:Reference searchBar}, Path=Text}"
EmptyViewTemplate="{StaticResource SearchSelector}"
Grid.Row="1" />
</Grid>
</ContentPage>
El código de C# equivalente es el siguiente:
SearchBar searchBar = new SearchBar { ... };
CollectionView collectionView = new CollectionView
{
EmptyView = searchBar.Text,
EmptyViewTemplate = new SearchTermDataTemplateSelector { ... }
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, static (MonkeysViewModel vm) => vm.Monkeys);
La propiedad EmptyView
se define en la propiedad SearchBar.Text
y la propiedad EmptyViewTemplate
, en un objeto SearchTermDataTemplateSelector
.
Cuando SearchBar ejecuta FilterCommand
, la colección mostrada por CollectionView se filtra para el término de búsqueda almacenado en la propiedad SearchBar.Text
. Si la operación de filtrado no produce ningún dato, la DataTemplate elegida por el objeto SearchTermDataTemplateSelector
se fija como la propiedad EmptyViewTemplate
y se muestra.
En el ejemplo siguiente se muestra la clase 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 clase SearchTermTemplateSelector
define DefaultTemplate
y OtherTemplate
DataTemplate propiedades que se establecen en diferentes plantillas de datos. La invalidación OnSelectTemplate
devuelve DefaultTemplate
, que muestra un mensaje al usuario, cuando la consulta de búsqueda no es igual a "xamarin". Cuando la consulta de búsqueda es igual a "xamarin", la invalidación OnSelectTemplate
devuelve OtherTemplate
, que muestra un mensaje básico al usuario:
Para obtener más información sobre los selectores de plantillas de datos, consulta Creación de un DataTemplateSelector.