Поделиться через


Xamarin.Forms CarouselView EmptyView

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

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

Эти свойства поддерживаются BindableProperty объектами, что означает, что свойства могут быть целевыми объектами привязки данных.

Основными сценариями использования для настройки EmptyView свойства являются отображение отзывов пользователей при CarouselView фильтрации без данных и отображение отзывов пользователей во время извлечения данных из веб-службы.

Примечание.

Свойство EmptyView можно задать для представления, включающего интерактивное содержимое при необходимости.

Дополнительные сведения о шаблонах данных см. в разделе Общие сведения о шаблонах данныхXamarin.Forms.

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

Свойство EmptyView может быть задано в строку, которая будет отображаться, когда ItemsSource свойство имеет nullзначение, или когда коллекция, указанная ItemsSource свойством, или null пуста. В следующем коде XAML показан пример этого сценария:

<CarouselView ItemsSource="{Binding EmptyMonkeys}"
              EmptyView="No items to display." />

Эквивалентный код на C# выглядит так:

CarouselView carouselView = new CarouselView
{
    EmptyView = "No items to display."
};
carouselView.SetBinding(ItemsView.ItemsSourceProperty, "EmptyMonkeys");

Результатом является то, что, так как коллекция nullпривязанных к данным данных, строка, заданная как EmptyView значение свойства, отображается.

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

Свойство EmptyView может быть задано в представлении, которое будет отображаться, если ItemsSource свойство равно nullили когда коллекция, указанная ItemsSource свойством null , или пуста. Это может быть одно представление или представление, содержащее несколько дочерних представлений. В следующем примере XAML показано EmptyView свойство, заданное для представления, содержащего несколько дочерних представлений:

<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>

В этом примере в качестве корневого EmptyViewэлемента добавлена избыточностьContentView. Это связано с тем, что внутренне добавляется в собственный контейнер, EmptyView который не предоставляет контекст для Xamarin.Forms макета. Поэтому для размещения представлений, составляющих ваши EmptyView, необходимо добавить корневой макет, дочерний объект которого является макетом, который может размещаться в корневом макете.

Эквивалентный код на C# выглядит так:

SearchBar searchBar = new SearchBar { ... };
CarouselView carouselView = new CarouselView
{
    EmptyView = new ContentView
    {
        Content = new StackLayout
        {
            Children =
            {
                new Label { Text = "No results matched your filter.", ... },
                new Label { Text = "Try a broader filter?", ... }
            }
        }
    }
};
carouselView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

SearchBar При выполнении FilterCommandколлекции, отображаемой CarouselView фильтром по термину поиска, хранящемуся в свойстве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={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>

Эквивалентный код на C# выглядит так:

SearchBar searchBar = new SearchBar { ... };
CarouselView carouselView = new CarouselView
{
    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коллекции, отображаемой CarouselView фильтром по термину поиска, хранящемуся в свойстве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"
             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>

Этот XAML определяет два ContentView объекта на уровне ResourceDictionaryстраницы с Switch объектом, определяющим, какой ContentView объект будет задан в качестве EmptyView значения свойства. Switch При переключение OnEmptyViewSwitchToggled обработчик событий выполняет ToggleEmptyView метод:

void ToggleEmptyView(bool isToggled)
{
    carouselView.EmptyView = isToggled ? Resources["BasicEmptyView"] : Resources["AdvancedEmptyView"];
}

Метод ToggleEmptyView задает EmptyView свойство carouselView объекта одному из двух ContentView объектов, хранящихся в объекте ResourceDictionary, на основе значения Switch.IsToggled свойства. SearchBar При выполнении FilterCommandколлекции, отображаемой CarouselView фильтром по термину поиска, хранящемуся в свойствеSearchBar.Text. Если операция фильтрации не дает данных, ContentView объект, заданный как EmptyView свойство отображается.

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

Выбор emptyViewTemplate во время выполнения

Внешний EmptyView вид объекта можно выбрать во время выполнения на основе его значения, задав CarouselView.EmptyViewTemplate свойство объекту DataTemplateSelector :

<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>

Эквивалентный код на C# выглядит так:

SearchBar searchBar = new SearchBar { ... };
CarouselView carouselView = new CarouselView()
{
    EmptyView = searchBar.Text,
    EmptyViewTemplate = new SearchTermDataTemplateSelector { ... }
};
carouselView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

Для EmptyView свойства задано SearchBar.Text свойство, а EmptyViewTemplate для SearchTermDataTemplateSelector свойства задано значение объекта.

SearchBar При выполнении FilterCommandколлекции, отображаемой CarouselView фильтром по термину поиска, хранящемуся в свойстве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".