Xamarin.Forms シェルでの検索
Xamarin.Forms シェルには、SearchHandler
クラスによって提供される統合された検索機能が組み込まれています。 検索機能は、Shell.SearchHandler
添付プロパティを、サブクラス化された SearchHandler
オブジェクトに設定することで、ページに追加できます。 これにより、検索ボックスがページの上部に追加されます。
検索ボックスにクエリが入力されると、Query
プロパティが更新され、更新のたびに OnQueryChanged
メソッドが実行されます。 このメソッドをオーバーライドして、検索候補領域にデータを設定できます。
次に、検索候補領域から結果が選択されると、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
に設定されると、ユーザーが検索クエリを入力したときに検索候補が表示されるようになります。
検索クエリが変更されると、検索候補領域が更新されます。
検索結果が選択されると、MonkeyDetailPage
にナビゲートされ、選択されたサルに関する詳細ページが表示されます。
検索結果の項目の外観を定義する
検索結果での 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
オブジェクトのプロパティにバインドされています。
次のスクリーンショットは、候補領域内の各項目をテンプレート化した結果を示しています。
データ テンプレートの詳細については、「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);