読者です 読者をやめる 読者になる 読者になる

ComponentOne Information

ComponentOne Studio/Wijmo/Xuniの最新情報を公開中

Xamarin.FormsのPickerにデータバインドする

最新版「Xamarin.Forms」の機能

クロスプラットフォームモバイルアプリ開発用のフレームワークであるXamarin.Fomrsは、日々成長を続けています。
2017年4月にリリースされた最新バージョン「2.3.4」では、意外にも(?)その機能が無かったPickerコントロールへのデータバインドが可能になりました。 リリースのお知らせでも「Bindable Picker」として紹介されています。

配列データをItemsSourceプロパティに設定することで、その内容選択肢のリストとして表示できます。

Xamarin.Formsアプリの開発

早速この機能を使ってみます。
Xamarin.FormsでAndroid、iOSアプリを開発するには、Visual StudioやXamarin Studioを利用します。
ここではその方法は解説しませんので他のサイトなどを参照してください。

Xamarin クロス プラットフォーム開発 - Visual Studio

Xamarin.Fomrs用のソリューションで、アプリ開発をする準備が整っている前提で解説します。


都道府県名を選択するPicker

Pickerコントロールを利用するのは簡単です。Xamarin.Formsのアセンブリに含まれていますので特別な準備は不要です。
最新パッケージをNuGetサーバーから更新することで、最新機能を利用できます。

コントロールを利用するにはエディタXAMLを開いて、ContentPageの中に<Picker>を定義します。
以下のコードでは、StackLayoutを利用して、Pickerと選択した内容を表示するためのラベルを、縦に並べて表示しています。
表示位置はページの中央です。ContentPageの内容以外は省略しています。

<StackLayout VerticalOptions="Center" Orientation="Vertical">

    <Label Text="Xamarin.Forms Picker (ピッカー)"/>
    
    <Picker ItemsSource="{Binding PrefDataSets}"
            ItemDisplayBinding="{Binding PrefName}"
            SelectedItem="{Binding SelectedData}" />

    <Label HorizontalOptions="Center"
            VerticalOptions="Center"
            Text="{Binding SelectedData.PrefName}" />

</StackLayout>

Pickerタグの中では、表示する選択肢の配列を指定するItemsSourceプロパティ、 選択肢として表示する内容を設定するItemDisplayBindingプロパティ、そして選択した内容を格納するSelectedItemプロパティに対し、後述するViewModelクラスの内容を接続しています。
今回、Bindableになったことを証明するためにも、フルにバインドしました。

次にこのページ(View)に対して、データを表示するためのクラス(ViewModel)を作成します。 まずはデータモデル(Model)。都道府県を表示するだけなのでシンプルにします。

// 都道府県名のデータモデル
public class PrefDataModel
{
    public string PrefName { get; set; } // 都道府県名
}

次にViewModelです。MVVMパターンを利用しますのでINotifyPropertyChangedインタフェースを実装したクラスを作ります。
内容は以下です。

  • Pickerコントロールで選択した内容を表示するためのプロパティSelectedData
  • 接続するためのListPrefNameとして定義
  • 都道府県名を表示する文字列と設定するコンストラクタ

以下のようなコードになります。

public class BindablePickerViewModel : INotifyPropertyChanged
{
    // 都道府県データ
    static string[] _prefnames = ("北海道|" +
            "青森|岩手|宮城|秋田|山形|福島|" +
            "茨城|栃木|群馬|埼玉|千葉|東京|神奈川|" +
            "新潟|富山|石川|福井|山梨|長野|岐阜|静岡|愛知|" +
            "三重|滋賀|京都|大阪|兵庫|奈良|和歌山|" +
            "鳥取|島根|岡山|広島|山口|" +
            "徳島|香川|愛媛|高知|" +
            "福岡|佐賀|長崎|熊本|大分|宮崎|鹿児島|沖縄").Split('|');

    public BindablePickerViewModel()
    {

        PrefDataSets = new List<PrefDataModel>();
        for (int i = 0; i < _prefnames.Length; i++)
        {
            PrefDataSets.Add(new PrefDataModel() { PrefName = _prefnames[i] });
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;

    // 都道府県名を格納するリスト  
    public List<PrefDataModel> PrefDataSets { get; }

    // 選択した内容を格納するプロパティ
    PrefDataModel _selectedData;
    public PrefDataModel SelectedData
    {
        get { return _selectedData; }
        set
        {
            if (value != _selectedData)
            {
                _selectedData = value;
                PropertyChanged(this, new PropertyChangedEventArgs(nameof(SelectedData)));
            }
        }
    }
}

作成したViewModel(ここではBindablePickerViewModelのクラス名)を、ContentPageBindingContext要素に設定すれば完了です。

<ContentPage.BindingContext>
    <Binding Source="{local:BindablePickerViewModel}"/>
</ContentPage.BindingContext>

前述でXAMLを作成したとき、以下のようにViewModelの内容と接続しました。
これでアプリを実行すれば接続した状態でデータが表示され、同じようにTextプロパティに接続済みの選択内容が画面に表示されます。

<Picker 
    ItemsSource="{Binding PrefDataSets}"
    ItemDisplayBinding="{Binding PrefName}"
    SelectedItem="{Binding SelectedData}" 
/>

<Label 
    HorizontalOptions="Center"
    VerticalOptions="Center"
    Text="{Binding SelectedData.PrefName}" 
/>

次の画像が表示結果です。
Xamarin.FormsのUIコントロールは各プラットフォームのAPIに置き換わりますので、左側のiOSでは画面の下部に選択画面が表示されますが、Androidの場合は選択画面で覆われる形になります。

f:id:ComponentOne_JP:20170414114920p:plain

選択肢を表示するPicker以外の選択肢

Pickerコントロールはタッチ操作だけで入力内容を選択できるので便利です。
しかし今回のように47個も選択肢がある場合にはあまり向きません。

その解決策のひとつとしてオートコンプリートコントロールがあります。 テキストを入力すれば、文字が含まれる選択肢を絞り込んで表示するための機能です。 文字入力の必要はありますが、必要な選択肢が候補として絞り込まれます。

Xamarin用UIコンポーネントセットのXuni(ズーニー)でもInputコントロールの機能として提供しています。
Inputコントロールを画面に追加してオートコンプリートを表示してみます。

Xuniの利用方法については別記事やWebサイトで公開している実装済みサンプルなどにありますのでそちらを参照してください。

Input コントロールを組み込む

NuGetからパッケージを追加し、ライセンスの設定が完了した後はXAMLにInputコントロールを組み込みます。
まず、ネームスペースを追記して、Inputのタグを追加します。ここで利用するコントロールは、オートコンプリート(XuniAutoComplete)です。 ItemsSourceにはPickerと同じPrefDataSetsをバインドします。

<xuni:XuniAutoComplete ItemsSource="{Binding PrefDataSets}" 
    DisplayMemberPath="PrefName" IsEditable="true">
</xuni:XuniAutoComplete>

これでピッカーと同様に候補がリスト形式で表示され、対象の項目を選択できます。

f:id:ComponentOne_JP:20170414115119p:plain

また、前述オートコンプリート機能があるので文字を入力することで候補を絞った表示が可能です。

f:id:ComponentOne_JP:20170414115150p:plain

このようにモバイルアプリは、入力を簡略化するユーザーインタフェースの有無が使い勝手の向上を考える場合に、重要なポイントになってきます。

Xuni Inputには、オートコンプリート以外にもコンボボックスやマスク入力などの機能があり、モバイルアプリのデータ入力画面作成に活用できます。

また、クイックスタートとして提供しているライセンスを組み込み済みのサンプルプロジェクトを利用して、Xuniの機能を実際にVisual StudioまたはXamarin Studioでお試しいただくことが可能です。

Xuniのはじめかた - クイックスタート | Xuni (ズーニー)


参考情報

New Bindable Picker Control for Xamarin.Forms | Xamarin Blog


ComponentOne