Events
Mar 17, 11 PM - Mar 21, 11 PM
Join the meetup series to build scalable AI solutions based on real-world use cases with fellow developers and experts.
Register nowThis browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
The .NET Multi-platform App UI (.NET MAUI) CarouselView defines the following properties that can be used to provide user feedback when there's no data to display:
EmptyView
, of type object
, the string, binding, or view that will be displayed when the ItemsSource
property is null
, or when the collection specified by the ItemsSource
property is null
or empty. The default value is null
.EmptyViewTemplate
, of type DataTemplate, the template to use to format the specified EmptyView
. The default value is null
.These properties are backed by BindableProperty objects, which means that the properties can be targets of data bindings.
The main usage scenarios for setting the EmptyView
property are displaying user feedback when a filtering operation on a CarouselView yields no data, and displaying user feedback while data is being retrieved from a web service.
Note
The EmptyView
property can be set to a view that includes interactive content if required.
For more information about data templates, see Data templates.
The EmptyView
property can be set to a string, which will be displayed when the ItemsSource
property is null
, or when the collection specified by the ItemsSource
property is null
or empty. The following XAML shows an example of this scenario:
<CarouselView ItemsSource="{Binding EmptyMonkeys}"
EmptyView="No items to display." />
The equivalent C# code is:
CarouselView carouselView = new CarouselView
{
EmptyView = "No items to display."
};
carouselView.SetBinding(ItemsView.ItemsSourceProperty, static (MonkeysViewModel vm) => vm.EmptyMonkeys);
The result is that, because the data bound collection is null
, the string set as the EmptyView
property value is displayed.
The EmptyView
property can be set to a view, which will be displayed when the ItemsSource
property is null
, or when the collection specified by the ItemsSource
property is null
or empty. This can be a single view, or a view that contains multiple child views. The following XAML example shows the EmptyView
property set to a view that contains multiple child views:
<StackLayout Margin="20">
<SearchBar SearchCommand="{Binding FilterCommand}"
SearchCommandParameter="{Binding Source={RelativeSource Self}, Path=Text}"
Placeholder="Filter" />
<CarouselView ItemsSource="{Binding Monkeys}">
<CarouselView.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>
</CarouselView.EmptyView>
<CarouselView.ItemTemplate>
...
</CarouselView.ItemTemplate>
</CarouselView>
</StackLayout>
In this example, what looks like a redundant has been added as the root element of the EmptyView
. This is because internally, the EmptyView
is added to a native container that doesn't provide any context for .NET MAUI layout. Therefore, to position the views that comprise your EmptyView
, you must add a root layout, whose child is a layout that can position itself within the root layout.
The equivalent C# code is:
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 { ... };
CarouselView carouselView = new CarouselView
{
EmptyView = new ContentView
{
Content = stackLayout
}
};
carouselView.SetBinding(ItemsView.ItemsSourceProperty, static (MonkeysViewModel vm) => vm.Monkeys);
When the SearchBar executes the FilterCommand
, the collection displayed by the CarouselView is filtered for the search term stored in the SearchBar.Text
property. If the filtering operation yields no data, the StackLayout set as the EmptyView
property value is displayed.
The EmptyView
property can be set to a custom type, whose template is displayed when the ItemsSource
property is null
, or when the collection specified by the ItemsSource
property is null
or empty. The EmptyViewTemplate
property can be set to a DataTemplate that defines the appearance of the EmptyView
. The following XAML shows an example of this scenario:
<StackLayout Margin="20">
<SearchBar x:Name="searchBar"
SearchCommand="{Binding FilterCommand}"
SearchCommandParameter="{Binding Source={RelativeSource Self}, Path=Text}"
Placeholder="Filter" />
<CarouselView ItemsSource="{Binding Monkeys}">
<CarouselView.EmptyView>
<controls:FilterData Filter="{Binding Source={x:Reference searchBar}, Path=Text}" />
</CarouselView.EmptyView>
<CarouselView.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>
</CarouselView.EmptyViewTemplate>
<CarouselView.ItemTemplate>
...
</CarouselView.ItemTemplate>
</CarouselView>
</StackLayout>
The equivalent C# code is:
SearchBar searchBar = new SearchBar { ... };
CarouselView carouselView = new CarouselView
{
EmptyView = new FilterData { Filter = searchBar.Text },
EmptyViewTemplate = new DataTemplate(() =>
{
return new Label { ... };
})
};
The FilterData
type defines a Filter
property, and a corresponding 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); }
}
}
The EmptyView
property is set to a FilterData
object, and the Filter
property data binds to the SearchBar.Text
property. When the SearchBar executes the FilterCommand
, the collection displayed by the CarouselView is filtered for the search term stored in the Filter
property. If the filtering operation yields no data, the Label defined in the DataTemplate, that's set as the EmptyViewTemplate
property value, is displayed.
Note
When displaying a templated custom type when data is unavailable, the EmptyViewTemplate
property can be set to a view that contains multiple child views.
Views that will be displayed as an EmptyView
when data is unavailable, can be defined as ContentView objects in a ResourceDictionary. The EmptyView
property can then be set to a specific ContentView, based on some business logic, at runtime. The following XAML example shows an example of this scenario:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodels="clr-namespace:CarouselViewDemos.ViewModels"
x:Class="CarouselViewDemos.Views.EmptyViewSwapPage"
Title="EmptyView (swap)">
<ContentPage.BindingContext>
<viewmodels:MonkeysViewModel />
</ContentPage.BindingContext>
<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 SearchCommand="{Binding FilterCommand}"
SearchCommandParameter="{Binding Source={RelativeSource Self}, Path=Text}"
Placeholder="Filter" />
<StackLayout Orientation="Horizontal">
<Label Text="Toggle EmptyViews" />
<Switch Toggled="OnEmptyViewSwitchToggled" />
</StackLayout>
<CarouselView x:Name="carouselView"
ItemsSource="{Binding Monkeys}">
<CarouselView.ItemTemplate>
...
</CarouselView.ItemTemplate>
</CarouselView>
</StackLayout>
</ContentPage>
This XAML defines two ContentView objects in the page-level ResourceDictionary, with the Switch object controlling which ContentView object will be set as the EmptyView
property value. When the Switch is toggled, the OnEmptyViewSwitchToggled
event handler executes the ToggleEmptyView
method:
void ToggleEmptyView(bool isToggled)
{
carouselView.EmptyView = isToggled ? Resources["BasicEmptyView"] : Resources["AdvancedEmptyView"];
}
The ToggleEmptyView
method sets the EmptyView
property of the CarouselView object to one of the two ContentView objects stored in the ResourceDictionary, based on the value of the Switch.IsToggled
property. When the SearchBar executes the FilterCommand
, the collection displayed by the CarouselView is filtered for the search term stored in the SearchBar.Text
property. If the filtering operation yields no data, the ContentView object set as the EmptyView
property is displayed.
For more information about resource dictionaries, see Resource dictionaries.
The appearance of the EmptyView
can be chosen at runtime, based on its value, by setting the CarouselView.EmptyViewTemplate
property to a DataTemplateSelector object:
<ContentPage ...
xmlns:controls="clr-namespace:CarouselViewDemos.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={RelativeSource Self}, Path=Text}"
Placeholder="Filter" />
<CarouselView ItemsSource="{Binding Monkeys}"
EmptyView="{Binding Source={x:Reference searchBar}, Path=Text}"
EmptyViewTemplate="{StaticResource SearchSelector}">
<CarouselView.ItemTemplate>
...
</CarouselView.ItemTemplate>
</CarouselView>
</StackLayout>
</ContentPage>
The equivalent C# code is:
SearchBar searchBar = new SearchBar { ... };
CarouselView carouselView = new CarouselView()
{
EmptyView = searchBar.Text,
EmptyViewTemplate = new SearchTermDataTemplateSelector { ... }
};
carouselView.SetBinding(ItemsView.ItemsSourceProperty, static (MonkeysViewModel vm) => vm.Monkeys);
The EmptyView
property is set to the SearchBar.Text
property, and the EmptyViewTemplate
property is set to a SearchTermDataTemplateSelector
object.
When the SearchBar executes the FilterCommand
, the collection displayed by the CarouselView is filtered for the search term stored in the SearchBar.Text
property. If the filtering operation yields no data, the DataTemplate chosen by the SearchTermDataTemplateSelector
object is set as the EmptyViewTemplate
property and displayed.
The following example shows the SearchTermDataTemplateSelector
class:
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;
}
}
The SearchTermTemplateSelector
class defines DefaultTemplate
and OtherTemplate
DataTemplate properties that are set to different data templates. The OnSelectTemplate
override returns DefaultTemplate
, which displays a message to the user, when the search query isn't equal to "xamarin". When the search query is equal to "xamarin", the OnSelectTemplate
override returns OtherTemplate
, which displays a basic message to the user.
For more information about data template selectors, see Create a DataTemplateSelector.
.NET MAUI feedback
.NET MAUI is an open source project. Select a link to provide feedback:
Events
Mar 17, 11 PM - Mar 21, 11 PM
Join the meetup series to build scalable AI solutions based on real-world use cases with fellow developers and experts.
Register nowTraining
Module
Design an MVVM viewmodel for .NET MAUI - Training
Discover how the MVVM design pattern can help separate your business logic and user interface code. Learn about how viewmodels are designed and why they're so important.
Documentation
Configure CarouselView interaction - .NET MAUI
The currently displayed item in a .NET MAUI CarouselView can be accessed through the CurrentItem and Position properties.
Control scrolling in a CarouselView - .NET MAUI
When a user swipes to initiate a scroll, the end position of the scroll can be controlled so that items are fully displayed. In addition, the .NET MAUI CarouselView defines two ScrollTo methods, that programmatically scroll items into view.
Populate a CarouselView with data - .NET MAUI
A .NET MAUI CarouselView is populated with data by setting its ItemsSource property to any collection that implements IEnumerable.