Syncfusion SfAutoComplete を使ってみる - Xamarin Forms
前回の投稿に引き続いて Syncfusion の Essential Studio for Xamarin を使ってみたいと思います。
↓↓↓前回↓↓↓
今回は SfAutoComplete を使ってみます。
SfAutoComplete は、テキストボックスへのユーザーの入力に対して、候補をオートコンプリート表示(&選択)するコントロールです。
ここでは、以下の2つの実装を紹介します。
1.シンプルな実装
→ 最もシンプルに、とりあえずSfAutoCompleteを使ってみます。2.かな入力 → 漢字で候補表示 & Prism で使ってみる
→ 駅名を「ひらがな」で入力。オートコンプリートでは「漢字の駅名」が候補表示される。オートコンプリートされた「漢字駅名」を選択すると、オートコンプリート内にも「漢字の駅名」が設定される。さらに Prism を使用。というサンプルを実装します。
で、以下で紹介するソースはGithubにあげてあります。
1. シンプルな実装
まず初めに、シンプルに SfAutoComplete を使ってみます。
ソリューションを新規作成します。
シンプルに「Cross-Platform → Blank Xaml App(Xamarin.Forms.Portable)」とします。
プロジェクト名は「AutoCompleteExample1」としました。
Nugetで SfAutoComplete への参照を追加
※SyncfusionのNugetを追加する方法についてはこちらの「Nugetソースの追加」の項を参照してください。
AutoCompleteExample1(PCLプロジェクト)には以下の参照をNugetで追加します。
- Syncfusion.Xamarin.SfAutoComplete
AutoCompleteExample1.Droid(androidプロジェクト)には以下の参照をNugetで追加します。
- Syncfusion.Xamarin.SfAutoComplete
- Syncfusion.Xamarin.SfAutoComplete.Android
AutoCompleteExample1.iOS(iOSプロジェクト)には以下の参照をNugetで追加します。
- Syncfusion.Xamarin.SfAutoComplete
- Syncfusion.Xamarin.SfAutoComplete.IOS
iOSプロジェクトに初期化処理を追加
AutoCompleteExample1.iOS プロジェクト→AppDelegate.cs内のFinishedLaunching()メソッドに「SfAutoCompleteRenderer」をインスタンス化する処理を追記します。
この記述がないと、iOSでは実行時に、画面に配置した SfAutoComplete が何の描画も行われません。
// AppDelegate.cs public override bool FinishedLaunching(UIApplication app, NSDictionary options) { // 以下を追記 new Syncfusion.SfAutoComplete.XForms.iOS.SfAutoCompleteRenderer(); global::Xamarin.Forms.Forms.Init(); LoadApplication(new App(new iOSInitializer())); return base.FinishedLaunching(app, options); }
フォームに配置
フォーム(MainForm.xaml)に SfAutoComplete コントロールを配置します。
<!-- MainPage.xaml --> <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:AutoCompleteExample1" xmlns:sf="clr-namespace:Syncfusion.SfAutoComplete.XForms;assembly=Syncfusion.SfAutoComplete.XForms" x:Class="AutoCompleteExample1.MainPage"> <StackLayout Margin="0,20,0,0"> <sf:SfAutoComplete x:Name="AutoComplete1" /> </StackLayout> </ContentPage>
ポイントは以下の通り。
① 「xmlns:sf」の指定
ルート要素
xmlns:sf=“clr-namespace:Syncfusion.SfAutoComplete.XForms;assembly=Syncfusion.SfAutoComplete.XForms”
上記により、Syncfusion.SfAutoComplete.XFormsアセンブリに実装されたSyncfusion.SfAutoComplete.XForms名前空間を、「sf」として利用可能になります。
② SfAutoCompleteの配置
<sf:SfAutoComplete>要素により SfAutoComplete コントロールをフォームに配置します。
候補文字列を追加
フォームに配置したSfAutoCompleteコントロールに候補文字列を追加します。
ここではコードビハインド上に以下のように実装を追加します。
// MainPage.xaml.cs using System.Collections.Generic; using Xamarin.Forms; namespace AutoCompleteExample1 { public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); // 候補文字列リストを作成 List<string> Stations = new List<string>(); Stations.Add("Tokyo"); Stations.Add("Osaka"); Stations.Add("Nagoya"); Stations.Add("Nagatachou"); Stations.Add("Ebisu"); Stations.Add("Sinagawa"); // SfAutoCompleteに候補文字列リストをソースとして設定 this.AutoComplete1.AutoCompleteSource = Stations; } } }
実行
実行すると以下のような画面が表示されます。
「Na」と入力。Nagoya / Nagatachou が候補として表示される。
「O」と入力。Osaka が候補として表示される。
ちょっと実装を追加
引き続き・・・フォームに「ボタン」と「ラベル」を追加します。
ボタンクリック時に SfAutoComplete に入力されている値をラベルに表示してみようと思います。
<!-- MainPage.xaml --> <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:AutoCompleteExample1" xmlns:sf="clr-namespace:Syncfusion.SfAutoComplete.XForms;assembly=Syncfusion.SfAutoComplete.XForms" x:Class="AutoCompleteExample1.MainPage"> <StackLayout Margin="0,20,0,0"> <sf:SfAutoComplete x:Name="AutoComplete1" /> <Label x:Name="Label1" /> <Button Text="入力項目チェック" Clicked="CheckClicked" /> </StackLayout> </ContentPage>
// MainPage.xaml.cs using System.Collections.Generic; using Xamarin.Forms; namespace AutoCompleteExample1 { public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); // 候補文字列リストを作成 List<string> Stations = new List<string>(); Stations.Add("Tokyo"); Stations.Add("Osaka"); Stations.Add("Nagoya"); Stations.Add("Nagatachou"); Stations.Add("Ebisu"); Stations.Add("Sinagawa"); // SfAutoCompleteに候補文字列リストをソースとして設定 this.AutoComplete1.AutoCompleteSource = Stations; } // ボタンクリックイベントハンドラ private void CheckClicked(object sender, System.EventArgs e) { // ラベルにSfAutoCompleteに入力された値を設定 this.Label1.Text = this.AutoComplete1.Text; } } }
さあ、実行!
「To」と入力して「Tokyo」が候補に挙がった。
「Tokyo」を選択。
「入力項目チェック」ボタンクリック。
2.かな入力 → 漢字で候補表示 & Prism で使ってみる
次に、もう少し面白みのあるサンプルを実装してみます。
要件は以下の通りです。
- 電車の駅名を入力するUIを想定する
- ユーザーは、駅名を「ひらがな」で入力する
- 「ひらがな」の入力に対して「漢字の駅名」を候補としてオートコンプリートする
- オートコンプリート候補の中から「漢字の駅名」を選択したら、SfAutoComplete内の表示も「漢字の駅名」となる
実行画面は以下のようになります。
ひらがな で「え」と入力すると、漢字の駅名が候補で表示される。
候補から「恵比寿」を選択。
「検索」ボタンをクリックすると、SfAutoCmopleteの入力内容が、下のラベルに表示される。
では、以下に実装を・・・
ソリューションを新規作成
「Prism Xamarin Forms → Prism Unity App(Xamarin.Forms)」とします。
プロジェクト名は「AutpCompleteWithPrism1」としました。
Nugetからの SfAutoComplete 参照の追加、iOSプロジェクト AppDelegate.cs へのコード追加は先程と同様。
Event to Command の下準備
本サンプルでは、Prism(MVVM)を使用します。
そして、SfAutoCompleteの「SelectionChangedイベント」を、ViewModelで捕捉したいです。
さらに、SelectionChangedはCommandとして提供されていません。
Viewのコードビハインドにコードを書きたくないし、MVVM的には「すべきではない」から。
という事で、「Event To Command」な実装が必要になります。
nuits.jpさんが以下の投稿で、いい感じの実装を提供してくれているので、これを拝借させていただきました。
以下の2ソースをPCLプロジェクトに追加しました。
Common/BindableBehavior.cs
→元ソースは以下
https://github.com/nuitsjp/XamarinSamples/blob/master/XFormsEventToCommand/XFormsEventToCommand/XFormsEventToCommand/BindableBehavior.csCommon/EventToCommandBehavior.cs
→元ソースは以下
https://github.com/nuitsjp/XamarinSamples/blob/master/XFormsEventToCommand/XFormsEventToCommand/XFormsEventToCommand/EventToCommandBehavior.cs
Stationモデルクラスを作成
先程のシンプルな実装では List
漢字名・ひらがな名を属性として持った駅クラスを用意するためです。
// Models/Station.cs using System; namespace AutpCompleteWithPrism1.Models { // 駅モデルクラス public class Station { /// <summary> /// 漢字駅名を取得または設定します。 /// </summary> public string Name { get; set; } /// <summary> /// ひらがな駅名を取得または設定します。 /// </summary> public string Kana { get; set; } } }
View(MainPage.xaml)を作成
ビュークラスは以下のように実装します。ポイントは後述。
<!-- Views/MainPage.xaml --> <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms" xmlns:common="clr-namespace:AutpCompleteWithPrism1.Common;assembly=AutpCompleteWithPrism1" xmlns:sf="clr-namespace:Syncfusion.SfAutoComplete.XForms;assembly=Syncfusion.SfAutoComplete.XForms" prism:ViewModelLocator.AutowireViewModel="True" x:Class="AutpCompleteWithPrism1.Views.MainPage" Title="MainPage"> <StackLayout HorizontalOptions="Center" VerticalOptions="Center"> <sf:SfAutoComplete DataSource="{Binding Stations}" DisplayMemberPath="Kana" Text="{Binding InputText}"> <sf:SfAutoComplete.ItemTemplate> <DataTemplate> <Label Text="{Binding Name}" /> </DataTemplate> </sf:SfAutoComplete.ItemTemplate> <sf:SfAutoComplete.Behaviors> <common:EventToCommandBehavior EventName="SelectionChanged" Command="{Binding SelectionChangedCommand}" /> </sf:SfAutoComplete.Behaviors> </sf:SfAutoComplete> <Button Text="検索" Command="{Binding SearchCommand}" /> <Label Text="{Binding Message}" /> </StackLayout> </ContentPage>
ポイントは以下の通り。
①SfAutoComlete / Button / Label の配置
SfAutoCompleteコントロールを配置します。
検索ボタン・ラベルを配置します。
検索ボタンクリック時には、ラベルに「SfAutoCompleteに入力された値」を表示します。
②SfAutoComplete.DataSourceの指定
カスタムクラスのコレクションを、オートコンプリート表示候補としてバインドする際には、DataSourceプロパティにデータソースを設定します。
③DisplayMemberPathの指定
オートコンプリート候補となるオブジェクト「Station」の、「どのプロパティ」を「表示項目(候補検索項目)」とするのかを指定します。
④ItemTemplateの指定
「ひらがなで入力、漢字名で候補を表示」の要件を満たすために、先のDisplayMemberPathには候補検索用としてKana(Station.Kane)を、漢字名表示用にカスタムなItemTemplate(Station.Nameを表示するように設定)を指定しています。
このItemTemplate の指定が無いと、候補の駅名が「ひらがな」で表示されてしまいます(DisplayMemberPathがKanaの為)。
⑤Event To Command Behavior の使用
以下のXML名前空間を定義。
xmlns:common=“clr-namespace:AutpCompleteWithPrism1.Common;assembly=AutpCompleteWithPrism1”
そして、SfAutoComplete の SelectionChangedイベント に Behavior を追加。
ViewModelを作成
ビューモデルクラスの実装は以下になります。
// ViewModels/MainPageViewModel.cs using Prism.Commands; using Prism.Mvvm; using Prism.Navigation; using System; using System.Collections.Generic; using System.Linq; using System.Windows.Input; using Xamarin.Forms; using AutpCompleteWithPrism1.Models; namespace AutpCompleteWithPrism1.ViewModels { public class MainPageViewModel : BindableBase, INavigationAware { /// <summary> /// SfAutoCompleteにデータバインドする駅情報データソース /// </summary> public List<Station> Stations { get; set; } = new List<Station>(); /// <summary> /// 検索ボタンコマンド /// </summary> public ICommand SearchCommand { get; } /// <summary> /// SfAutoComplete選択項目変更コマンド /// </summary> public ICommand SelectionChangedCommand { get; } /// <summary> /// SfAutoComplete入力テキスト /// </summary> private string inputText = ""; public string InputText { get { return this.inputText; } set { this.SetProperty(ref this.inputText, value); } } /// <summary> /// メッセージテキスト /// </summary> private string message = ""; public string Message { get { return this.message; } set { this.SetProperty(ref this.message, value); } } public MainPageViewModel() { // データソース作成 this.Stations.Add(new Station() { Name = "東京", Kana = "とうきょう" }); this.Stations.Add(new Station() { Name = "恵比寿", Kana = "えびす" }); this.Stations.Add(new Station() { Name = "江戸橋", Kana = "えどばし" }); this.Stations.Add(new Station() { Name = "品川", Kana = "しながわ" }); this.Stations.Add(new Station() { Name = "新宿", Kana = "しんじゅく" }); // SfAutoComplete.SelectionChangedイベントに対応したCommand SelectionChangedCommand = new Command((param) => { this.InputText = this.Stations.First(s => s.Kana == ((Syncfusion.SfAutoComplete.XForms.SelectionChangedEventArgs)param).Value).Name; }); // 検索ボタンクリック時のCommand SearchCommand = new Command(() => { this.Message = this.InputText; }); } public void OnNavigatedFrom(NavigationParameters parameters) { } public void OnNavigatedTo(NavigationParameters parameters) { } } }
ポイントは以下の通り。
①SfAutoComleteのデータソースを用意
List
②SelectionChangedCommand の実装
SfAutoCompleteの「候補」が選択されたときに発生するイベントをBehavior経由でSelectionChangedCommandとして取得します。
その際には、パラメータ「Syncfusion.SfAutoComplete.XForms.SelectionChangedEventArgs型 Param 」から、選択された値「ひらがな」名を取得し、該当するStationモデルクラスのName(漢字駅名)をInputTextプロパティに設定しています。
InputTextプロパティは、ViewにおいてShAutoComplete.Textにバインドされています。
つまり、以下のような動作が行われます。
SfAutoCompleteにユーザーが「ひらがな」入力
↓↓↓
候補として「ひらがな」に該当する Kanaプロパティ を持つ Stationオブジェクト の漢字駅名が候補一覧される
↓↓↓
ユーザーが漢字駅名を選択
↓↓↓
SelectionChangedCommandが発生
↓↓↓
ViewModelのInputTextプロパティ値に、選択されたStationモデルクラスに該当する「漢字駅名」を設定
↓↓↓
SfAutoComplete.Textに、ViewModel.InputText値が反映される(つまり漢字駅名)
③SearchCommand の実装
検索ボタンコマンドの実装です。
InputTextの値(つまりSfAutoCompleteの入力値)を、Messageプロパティに設定します。
Messageプロパティはビューのラベルにバインドされています。
まとめ
ということで「Syncfusionを使ってみる シリーズ(?)」第2回でした。
SfAutoCompleteは、すごくシンプルで僅かな英語力であっても、以下のヘルプを読めばすぐに理解できました。
が、「ひらがな入力→漢字表示」みたいな、非英語圏(日本)のちょっとした要件を満たす部分には、若干の調査が必要でした・・・
ちょっとイレギュラーな利用方法をしているような気がするので、その使い方だと「こんな時におかしくなるよー」とかありましたらご指摘お願いいたします。
ということで、「Syncfusionを使ってみる」は引き続き、本ブログでシリーズ化していきたいな、と思っています!