Xamarin.Forms シェルでの検索

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

Xamarin.Forms シェルには、SearchHandler クラスによって提供される統合された検索機能が組み込まれています。 検索機能は、Shell.SearchHandler 添付プロパティを、サブクラス化された SearchHandler オブジェクトに設定することで、ページに追加できます。 これにより、検索ボックスがページの上部に追加されます。

Screenshot of a Shell SearchHandler, on iOS and Android

検索ボックスにクエリが入力されると、Query プロパティが更新され、更新のたびに OnQueryChanged メソッドが実行されます。 このメソッドをオーバーライドして、検索候補領域にデータを設定できます。

Screenshot of a search results in a Shell SearchHandler, on iOS and Android

次に、検索候補領域から結果が選択されると、OnItemSelected メソッドが実行されます。 このメソッドは、詳細ページに移動するなどによって、適切に応答するようにオーバーライドできます。

SearchHandler を作成する

検索機能は、SearchHandler クラスをサブクラス化して OnQueryChanged および OnItemSelected メソッドをオーバーライドすることで、シェル アプリケーションに追加できます。

public class AnimalSearchHandler : SearchHandler
{
    public IList<Animal> Animals { get; set; }
    public Type SelectedItemNavigationTarget { get; set; }

    protected override void OnQueryChanged(string oldValue, string newValue)
    {
        base.OnQueryChanged(oldValue, newValue);

        if (string.IsNullOrWhiteSpace(newValue))
        {
            ItemsSource = null;
        }
        else
        {
            ItemsSource = Animals
                .Where(animal => animal.Name.ToLower().Contains(newValue.ToLower()))
                .ToList<Animal>();
        }
    }

    protected override async void OnItemSelected(object item)
    {
        base.OnItemSelected(item);

        // Let the animation complete
        await Task.Delay(1000);

        ShellNavigationState state = (App.Current.MainPage as Shell).CurrentState;
        // The following route works because route names are unique in this application.
        await Shell.Current.GoToAsync($"{GetNavigationTarget()}?name={((Animal)item).Name}");
    }

    string GetNavigationTarget()
    {
        return (Shell.Current as AppShell).Routes.FirstOrDefault(route => route.Value.Equals(SelectedItemNavigationTarget)).Key;
    }
}

OnQueryChanged オーバーライドには、2 つの引数があります。前回の検索クエリを格納する oldValue と、現在の検索クエリを格納する newValue です。 検索候補領域は、SearchHandler.ItemsSource プロパティを、現在の検索クエリと一致する項目を含む IEnumerable コレクションに設定することで更新できます。

検索結果がユーザーによって選択されると、OnItemSelected オーバーライドが実行されて、SelectedItem プロパティが設定されます。 この例では、メソッドによって、選択した Animal に関するデータを表示した別のページへナビゲートされます。 ナビゲーションの詳細については、「Xamarin.Forms シェルのナビゲーション」を参照してください。

Note

追加の SearchHandler プロパティを設定することで、検索ボックスの外観を制御できます。

SearchHandler を使用する

サブクラス化された SearchHandler は、使用しているページ上で Shell.SearchHandler 添付プロパティを、サブクラス化された型のオブジェクトに設定することで使用できます。

<ContentPage ...
             xmlns:controls="clr-namespace:Xaminals.Controls">
    <Shell.SearchHandler>
        <controls:AnimalSearchHandler Placeholder="Enter search term"
                                      ShowsResults="true"
                                      DisplayMemberName="Name" />
    </Shell.SearchHandler>
    ...
</ContentPage>

同等の C# コードを次に示します。

Shell.SetSearchHandler(this, new AnimalSearchHandler
{
    Placeholder = "Enter search term",
    ShowsResults = true,
    DisplayMemberName = "Name"
});

AnimalSearchHandler.OnQueryChanged メソッドは、Animal オブジェクトの List を返します。 DisplayMemberName プロパティは各 Animal オブジェクトの Name プロパティに設定されるので、候補領域に表示されるデータは各動物の名前になります。

ShowsResults プロパティが true に設定されると、ユーザーが検索クエリを入力したときに検索候補が表示されるようになります。

Screenshot of search results in a Shell SearchHandler, on iOS and Android, with results for the partial string M.

検索クエリが変更されると、検索候補領域が更新されます。

Screenshot of search results in a Shell SearchHandler, on iOS and Android, with results for the partial string M o n.

検索結果が選択されると、MonkeyDetailPage にナビゲートされ、選択されたサルに関する詳細ページが表示されます。

Screenshot of monkey details, on iOS and Android

検索結果の項目の外観を定義する

検索結果での string データの表示に加えて、SearchHandler.ItemTemplate プロパティを DataTemplate に設定することで、各検索結果項目の外観を定義できます。

<ContentPage ...
             xmlns:controls="clr-namespace:Xaminals.Controls">    
    <Shell.SearchHandler>
        <controls:AnimalSearchHandler Placeholder="Enter search term"
                                      ShowsResults="true">
            <controls:AnimalSearchHandler.ItemTemplate>
                <DataTemplate>
                    <Grid Padding="10"
                          ColumnDefinitions="0.15*,0.85*">
                        <Image Source="{Binding ImageUrl}"
                               HeightRequest="40"
                               WidthRequest="40" />
                        <Label Grid.Column="1"
                               Text="{Binding Name}"
                               FontAttributes="Bold"
                               VerticalOptions="Center" />
                    </Grid>
                </DataTemplate>
            </controls:AnimalSearchHandler.ItemTemplate>
       </controls:AnimalSearchHandler>
    </Shell.SearchHandler>
    ...
</ContentPage>

同等の C# コードを次に示します。

Shell.SetSearchHandler(this, new AnimalSearchHandler
{
    Placeholder = "Enter search term",
    ShowsResults = true,
    ItemTemplate = new DataTemplate(() =>
    {
        Grid grid = new Grid { Padding = 10 };
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.15, GridUnitType.Star) });
        grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(0.85, GridUnitType.Star) });

        Image image = new Image { HeightRequest = 40, WidthRequest = 40 };
        image.SetBinding(Image.SourceProperty, "ImageUrl");
        Label nameLabel = new Label { FontAttributes = FontAttributes.Bold, VerticalOptions = LayoutOptions.Center };
        nameLabel.SetBinding(Label.TextProperty, "Name");

        grid.Children.Add(image);
        grid.Children.Add(nameLabel, 1, 0);
        return grid;
    })
});

DataTemplate に指定された要素では、候補領域にある各項目の外観を定義します。 この例では、DataTemplate 内のレイアウトは Grid によって管理されています。 Grid には Image オブジェクトと Label オブジェクトが格納され、両方とも各 Monkey オブジェクトのプロパティにバインドされています。

次のスクリーンショットは、候補領域内の各項目をテンプレート化した結果を示しています。

Screenshot of templated search results in a Shell SearchHandler, on iOS and Android

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

検索ボックスの表示

既定では、SearchHandler がページの上部に追加されると、検索ボックスが表示され、完全に展開されます。 しかし、SearchHandler.SearchBoxVisibility プロパティを SearchBoxVisibility 列挙メンバーのいずれかに設定することで、この動作を変更することができます。

  • Hidden – 検索ボックスは表示されず、アクセスできません。
  • Collapsible – 表示するためのアクションをユーザーが実行するまで、検索ボックスは非表示になります。 iOS では、ページのコンテンツを垂直方向にバウンスさせることで検索ボックスが表示されます。Android では、疑問符アイコンをタップすると検索ボックスが表示されます。
  • Expanded – 検索ボックスは表示され、完全に展開されます。 これは、SearchBoxVisibility プロパティの既定値です。

重要

iOS では、折りたたみ可能な検索ボックスには iOS 11 以上が必要です。

次の例は、検索ボックスを非表示にする方法を示しています。

<ContentPage ...
             xmlns:controls="clr-namespace:Xaminals.Controls">
    <Shell.SearchHandler>
        <controls:AnimalSearchHandler SearchBoxVisibility="Hidden"
                                      ... />
    </Shell.SearchHandler>
    ...
</ContentPage>

検索ボックスのフォーカス

検索ボックスをタップすると、検索ボックスが入力フォーカスを取得して、オンスクリーン キーボードが呼び出されます。 これは、プログラムで実現することもできます。それには、Focus メソッドを呼び出します。これにより、検索ボックスに入力フォーカスを設定することが試みられ、成功すると true が返されます。 検索ボックスにフォーカスが設定されると、Focused イベントが発生し、オーバーライド可能な OnFocused メソッドが呼び出されます。

検索ボックスに入力フォーカスがあるときに、画面上の他の場所をタップすると、オンスクリーン キーボードが消去され、検索ボックスから入力フォーカスが失われます。 これはまた、Unfocus メソッドを呼び出すことによって、プログラムでも実現できます。 検索ボックスからフォーカスが失われると、Unfocused イベントが発生し、オーバーライド可能な OnUnfocus メソッドが呼び出されます。

検索ボックスのフォーカス状態は、IsFocused プロパティから取得できます。これにより、SearchHandler に現在入力フォーカスがある場合に true が返されます。

SearchHandler キーボード

ユーザーが SearchHandler とやりとりする際に表示されるキーボードは、Keyboard プロパティを使用することで、Keyboard クラスの次のいずれかのプロパティにプログラムによって設定できます。

  • Chat - 絵文字が使えるテキスト メッセージや場所に使います。
  • Default - 既定のキーボード。
  • Email - 電子メール アドレスを入力するときに使用します。
  • Numeric - 数値を入力するときに使用します。
  • Plain - KeyboardFlags を指定しないで、テキストを入力するときに使用します。
  • Telephone - 電話番号を入力するときに使用します。
  • Text - テキストを入力するときに使用します。
  • Url - ファイル パスおよび Web アドレスを入力するために使用します。

XAML では次のようにしてこれを実現できます。

<SearchHandler Keyboard="Email" />

同等の C# コードを次に示します。

SearchHandler searchHandler = new SearchHandler { Keyboard = Keyboard.Email };

Keyboard クラスには、大文字の設定、スペルチェック、および単語補完候補の動作を指定することで、キーボードをカスタマイズするために使用できる Create ファクトリ メソッドもあります。 KeyboardFlags 列挙値がメソッドへの引数として指定され、カスタマイズされた Keyboard が返されます。 KeyboardFlags 列挙体には次の値が含まれます。

  • None - キーボードに機能は追加されません。
  • CapitalizeSentence - 入力された各文の最初の単語の最初の文字が自動的に大文字になることを示します。
  • Spellcheck - 入力したテキストに対してスペル チェックが実行されることを示します。
  • Suggestions - 入力したテキストに対して単語補完が提供されることを示します。
  • CapitalizeWord - 各単語の最初の文字が自動的に大文字になることを示します。
  • CapitalizeCharacter - すべての文字が自動的に大文字になることを示します。
  • CapitalizeNone - 大文字の自動設定を行わないことを示します。
  • All - 入力したテキストに対して、スペルチェック、単語補完、および文への大文字の設定が行われることを示します。

次の XAML コード例は、既定の Keyboard をカスタマイズして、単語補完を提供し、入力したすべての文字を大文字に設定する方法を示しています。

<SearchHandler Placeholder="Enter search terms">
    <SearchHandler.Keyboard>
        <Keyboard x:FactoryMethod="Create">
            <x:Arguments>
                <KeyboardFlags>Suggestions,CapitalizeCharacter</KeyboardFlags>
            </x:Arguments>
        </Keyboard>
    </SearchHandler.Keyboard>
</SearchHandler>

同等の C# コードを次に示します。

SearchHandler searchHandler = new SearchHandler { Placeholder = "Enter search terms" };
searchHandler.Keyboard = Keyboard.Create(KeyboardFlags.Suggestions | KeyboardFlags.CapitalizeCharacter);