Xamarin.Forms カルーセルビュー EmptyView

サンプルのダウンロードサンプルのダウンロード

CarouselView は、表示するデータがない場合にユーザーフィードバックを提供するために使用できる次のプロパティを定義します。

  • EmptyView型の object、プロパティが の場合、または プロパティnullItemsSourcenull指定されたコレクションがまたは空の場合ItemsSourceに表示される文字列、バインド、またはビュー。 既定値は null です。
  • EmptyViewTemplateDataTemplateの 。指定した EmptyViewの書式を設定するために使用するテンプレート。 既定値は null です。

これらのプロパティはオブジェクトによって BindableProperty サポートされます。つまり、プロパティはデータ バインディングのターゲットにすることができます。

プロパティを設定EmptyViewするためのメインの使用シナリオは、 に対するフィルター処理操作でデータが生成されない場合にCarouselViewユーザー フィードバックを表示し、Web サービスからデータを取得している間にユーザー フィードバックを表示することです。

注意

プロパティは EmptyView 、必要に応じて対話型コンテンツを含むビューに設定できます。

データ テンプレートの詳細については、「Xamarin.Forms のデータ テンプレート」を参照してください。

データが使用できないときに文字列を表示する

プロパティをEmptyView文字列に設定できます。これは、 プロパティが の場合ItemsSource、または プロパティnullで指定されたコレクションが null または 空の場合にItemsSource表示されます。 次の 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ビューに設定できます。このビューは、 プロパティが nullの場合ItemsSource、または プロパティで指定されたコレクションが null または 空の場合にItemsSource表示されます。 1 つのビュー、または複数の子ビューを含むビューを指定できます。 次の 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");

SearchBarFilterCommand実行すると、 によって CarouselView 表示されるコレクションが、 プロパティに格納されている検索用語に対して SearchBar.Text フィルター処理されます。 フィルター処理操作でデータが生成されない場合は、 StackLayout プロパティ値として EmptyView 設定された が表示されます。

データが使用できないときにテンプレート化されたカスタム型を表示する

プロパティはEmptyView、カスタム型に設定できます。この型のテンプレートは、 プロパティが nullの場合ItemsSource、または プロパティで指定されたコレクションがnullまたは空の場合にItemsSource表示されます。 プロパティは 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 バインドされます。 が SearchBarFilterCommand実行すると、 によって CarouselView 表示されるコレクションが、 プロパティに格納されている検索用語に対して Filter フィルター処理されます。 フィルター処理操作でデータが生成されない場合は、Labelプロパティ値としてEmptyViewTemplate設定された でDataTemplate定義されている が表示されます。

注意

データが使用できないときにテンプレート化されたカスタム型を表示する場合、 プロパティは、 EmptyViewTemplate 複数の子ビューを含むビューに設定できます。

実行時に EmptyView を選択する

データが使用できないときに としてEmptyView表示されるビューは、 内のResourceDictionaryオブジェクトとしてContentView定義できます。 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 では、ページ レベルResourceDictionaryで 2 つのContentViewオブジェクトを定義し、どのオブジェクトをSwitchプロパティ値として設定するかをContentView制御する オブジェクトをEmptyView定義します。 を Switch 切り替えると、イベント ハンドラーは OnEmptyViewSwitchToggled メソッドを ToggleEmptyView 実行します。

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

メソッドはToggleEmptyViewEmptyView プロパティの値Switch.IsToggledに基づいて、 オブジェクトの carouselView プロパティを にResourceDictionary格納されている 2 つのContentViewオブジェクトのいずれかに設定します。 が SearchBarFilterCommand実行すると、 によって 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設定されます。

SearchBarFilterCommand実行すると、 によって 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;
    }
}

クラスは SearchTermTemplateSelectorDefaultTemplate 異なるデータ テンプレートに設定される プロパティと OtherTemplateDataTemplate プロパティを定義します。 オーバーライドは OnSelectTemplate を返 DefaultTemplateします。これにより、検索クエリが "xamarin" と等しくない場合に、ユーザーにメッセージが表示されます。 検索クエリが "xamarin" と等しい場合、 OnSelectTemplate オーバーライドは を返 OtherTemplateします。これにより、ユーザーに基本的なメッセージが表示されます。

データ テンプレート セレクターの詳細については、「 DataTemplateSelector の Xamarin.Forms 作成」を参照してください。