Xamarin.Forms CollectionView EmptyView
CollectionView
определяет следующие свойства, которые можно использовать для предоставления отзывов пользователей при отсутствии данных для отображения:
EmptyView
, типobject
, строка, привязка или представление, которое будет отображаться, когдаItemsSource
свойство имеетnull
значение, или когда коллекция, указаннаяItemsSource
свойствомnull
, или пуста. Значение по умолчанию —null
.EmptyViewTemplate
DataTemplate
Тип , шаблон, используемый для форматирования указанногоEmptyView
. Значение по умолчанию —null
.
Эти свойства поддерживаются BindableProperty
объектами, что означает, что свойства могут быть целевыми объектами привязки данных.
Основными сценариями использования для настройки EmptyView
свойства являются отображение отзывов пользователей при CollectionView
фильтрации без данных и отображение отзывов пользователей во время извлечения данных из веб-службы.
Примечание.
Свойство EmptyView
можно задать для представления, включающего интерактивное содержимое при необходимости.
Дополнительные сведения о шаблонах данных см. в разделе Общие сведения о шаблонах данныхXamarin.Forms.
Отображение строки при недоступности данных
Свойство EmptyView
может быть задано в строку, которая будет отображаться, когда ItemsSource
свойство имеет null
значение, или когда коллекция, указанная ItemsSource
свойством, или null
пуста. В следующем коде XAML показан пример этого сценария:
<CollectionView ItemsSource="{Binding EmptyMonkeys}"
EmptyView="No items to display" />
Эквивалентный код на C# выглядит так:
CollectionView collectionView = new CollectionView
{
EmptyView = "No items to display"
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "EmptyMonkeys");
Результатом является то, что, поскольку коллекция null
привязанных к данным данных, строка, заданная в качестве EmptyView
значения свойства, отображается:
Отображение представлений при недоступности данных
Свойство EmptyView
может быть задано в представлении, которое будет отображаться, если ItemsSource
свойство равно null
или когда коллекция, указанная ItemsSource
свойством null
, или пуста. Это может быть одно представление или представление, содержащее несколько дочерних представлений. В следующем примере XAML показано EmptyView
свойство, заданное для представления, содержащего несколько дочерних представлений:
<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>
В этом примере в качестве корневого EmptyView
элемента добавлена избыточностьContentView
. Это связано с тем, что внутренне добавляется в собственный контейнер, EmptyView
который не предоставляет контекст для Xamarin.Forms макета. Поэтому для размещения представлений, составляющих ваши EmptyView
, необходимо добавить корневой макет, дочерний объект которого является макетом, который может размещаться в корневом макете.
Эквивалентный код на C# выглядит так:
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");
SearchBar
При выполнении FilterCommand
коллекции, отображаемой CollectionView
фильтром по термину поиска, хранящемуся в свойствеSearchBar.Text
. Если операция фильтрации не дает данных, StackLayout
отображается значение EmptyView
свойства:
Отображение шаблонного пользовательского типа при недоступности данных
Свойство EmptyView
можно задать для пользовательского типа, шаблон которого отображается, когда ItemsSource
свойство имеет null
значение, или когда коллекция, указанная ItemsSource
свойством, или null
пуста. Свойство EmptyViewTemplate
может быть задано в значение DataTemplate
, определяющее внешний EmptyView
вид объекта. В следующем коде XAML показан пример этого сценария:
<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>
Эквивалентный код на C# выглядит так:
SearchBar searchBar = new SearchBar { ... };
CollectionView collectionView = new CollectionView
{
EmptyView = new FilterData { Filter = searchBar.Text },
EmptyViewTemplate = new DataTemplate(() =>
{
return new Label { ... };
})
};
Тип FilterData
определяет Filter
свойство и соответствующее 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); }
}
}
Свойство EmptyView
присваивается FilterData
объекту, а Filter
данные свойств привязываются к свойству SearchBar.Text
. SearchBar
При выполнении FilterCommand
коллекции, отображаемой CollectionView
фильтром по термину поиска, хранящемуся в свойствеFilter
. Если операция фильтрации не дает данных, Label
то в качестве значения свойства отображается определенное в DataTemplate
EmptyViewTemplate
качестве значения свойства:
Примечание.
При отображении шаблонного пользовательского типа при недоступности EmptyViewTemplate
данных свойство можно задать для представления, содержащего несколько дочерних представлений.
Выбор EmptyView во время выполнения
Представления, которые будут отображаться как EmptyView
недоступные данные, можно определить как ContentView
объекты в объекте ResourceDictionary
. Затем EmptyView
свойство может быть задано на основе определенной ContentView
бизнес-логики во время выполнения. В следующем коде XAML показан пример этого сценария:
<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>
Этот XAML определяет два ContentView
объекта на уровне ResourceDictionary
страницы с Switch
объектом, определяющим, какой ContentView
объект будет задан в качестве EmptyView
значения свойства. Switch
При переключение OnEmptyViewSwitchToggled
обработчик событий выполняет ToggleEmptyView
метод:
void ToggleEmptyView(bool isToggled)
{
collectionView.EmptyView = isToggled ? Resources["BasicEmptyView"] : Resources["AdvancedEmptyView"];
}
Метод ToggleEmptyView
задает EmptyView
свойство collectionView
объекта одному из двух ContentView
объектов, хранящихся в объекте ResourceDictionary
, на основе значения Switch.IsToggled
свойства. SearchBar
При выполнении FilterCommand
коллекции, отображаемой CollectionView
фильтром по термину поиска, хранящемуся в свойствеSearchBar.Text
. Если операция фильтрации не дает данных, объект, заданный в качестве EmptyView
свойства, ContentView
отображается:
Дополнительные сведения о словарях ресурсов см. в разделах Xamarin.Forms "Словари ресурсов".
Выбор emptyViewTemplate во время выполнения
Внешний EmptyView
вид объекта можно выбрать во время выполнения на основе его значения, задав CollectionView.EmptyViewTemplate
свойство объекту 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>
Эквивалентный код на C# выглядит так:
SearchBar searchBar = new SearchBar { ... };
CollectionView collectionView = new CollectionView
{
EmptyView = searchBar.Text,
EmptyViewTemplate = new SearchTermDataTemplateSelector { ... }
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
Для EmptyView
свойства задано SearchBar.Text
свойство, а EmptyViewTemplate
для SearchTermDataTemplateSelector
свойства задано значение объекта.
SearchBar
При выполнении FilterCommand
коллекции, отображаемой CollectionView
фильтром по термину поиска, хранящемуся в свойствеSearchBar.Text
. Если операция фильтрации не дает данных, DataTemplate
выбранный SearchTermDataTemplateSelector
объектом, устанавливается как EmptyViewTemplate
свойство и отображается.
В следующем примере показан 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;
}
}
Класс SearchTermTemplateSelector
определяет DefaultTemplate
и OtherTemplate
DataTemplate
свойства, которые задаются различными шаблонами данных. Возвращается OnSelectTemplate
DefaultTemplate
переопределение, отображающее сообщение пользователю, если поисковый запрос не равен "xamarin". Когда поисковый запрос равен "xamarin", переопределение возвращаетсяOtherTemplate
, OnSelectTemplate
которое отображает базовое сообщение пользователю:
Дополнительные сведения о селекторах шаблонов данных см. в разделе "Создание Xamarin.Forms объекта DataTemplateSelector".