Xamarin.Forms CollectionView EmptyView

Download Sample Скачайте пример

CollectionView определяет следующие свойства, которые можно использовать для предоставления отзывов пользователей при отсутствии данных для отображения:

  • EmptyView, тип object, строка, привязка или представление, которое будет отображаться, когда ItemsSource свойство имеет nullзначение, или когда коллекция, указанная ItemsSource свойством null , или пуста. Значение по умолчанию — null.
  • EmptyViewTemplateDataTemplateТип , шаблон, используемый для форматирования указанного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 значения свойства, отображается:

Screenshot of a CollectionView vertical list with a text empty view, on iOS and Android

Отображение представлений при недоступности данных

Свойство 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 свойства:

Screenshot of a CollectionView vertical list with custom empty view, on iOS and Android

Отображение шаблонного пользовательского типа при недоступности данных

Свойство 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 то в качестве значения свойства отображается определенное в DataTemplateEmptyViewTemplate качестве значения свойства:

Screenshot of a CollectionView vertical list with an empty view template, on iOS and Android

Примечание.

При отображении шаблонного пользовательского типа при недоступности 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 отображается:

Screenshot of a CollectionView vertical list with swapped empty views, on iOS and Android

Дополнительные сведения о словарях ресурсов см. в разделах 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 и OtherTemplateDataTemplate свойства, которые задаются различными шаблонами данных. Возвращается OnSelectTemplateDefaultTemplateпереопределение, отображающее сообщение пользователю, если поисковый запрос не равен "xamarin". Когда поисковый запрос равен "xamarin", переопределение возвращаетсяOtherTemplate, OnSelectTemplate которое отображает базовое сообщение пользователю:

Screenshot of a CollectionView runtime empty view template selection, on iOS and Android

Дополнительные сведения о селекторах шаблонов данных см. в разделе "Создание Xamarin.Forms объекта DataTemplateSelector".