ぴーさんログ

だいたいXamarin.Formsのブログ

【Xamarin.Forms 2.1.0(プレビュー)】DataTemplateSelector

Xamarin.Forms 2.1.0 で DataTemplateSelector が追加される予定です。

DataTemplateSelector を簡単に説明すると 「条件に応じたDataTemplateを返すDataTemplate」 です。

サンプル

サンプルとして、各セルのデータ型に合わせたテンプレートを返すDataTemplateSelectorを作成してみましょう。 DataTemplateSelectorを継承し、OnSelectTemplate()を実装します。

public class MyDataTemplateSelector : DataTemplateSelector
{
    private readonly DataTemplate defaulTemplate;
    private readonly Dictionary<Type, DataTemplate> templateSet;

    public MyDataTemplateSelector(Dictionary<Type, DataTemplate> templateSet)
    {
        this.templateSet = templateSet;

        defaulTemplate = new DataTemplate(typeof(TextCell));
        defaulTemplate.SetBinding(TextCell.TextProperty, new Binding(".", stringFormat:"{0}"));
    }

    #region implemented abstract members of DataTemplateSelector
    // itemにはセルのデータ、containerにはセルの親(ListViewやTableView)が渡される
    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        DataTemplate template;
        if(templateSet != null && 
            templateSet.TryGetValue(item.GetType(), out template))
        {
            return template;
        }

        return defaulTemplate;
    }
    #endregion
}

利用側のコードはこんな感じ。

public App()
{
    var colorTemplate = new DataTemplate(typeof(TextCell));
    colorTemplate.SetBinding(TextCell.TextProperty, new Binding(".", stringFormat: "Color:{0}"));
    colorTemplate.SetBinding(TextCell.TextColorProperty, ".");

    var boolTemplate = new DataTemplate(typeof(SwitchCell));
    boolTemplate.SetBinding(SwitchCell.OnProperty, ".");

    var templateSelector = new MyDataTemplateSelector(
        new Dictionary<Type, DataTemplate> {
            {typeof(Color), colorTemplate},
            {typeof(bool), boolTemplate},
    });
    
    MainPage = new ContentPage {
        Content = new ListView {
            ItemTemplate = templateSelector,
            ItemsSource = new object [] {
                Color.Blue,
                false,
                true,
                Color.Red,
                Color.Teal,
                true,
                "Hello World", // ここからはデフォルトテンプレートの確認用
                1,
                33.4,
            },
        }
    };
}

結果はこのようになります。

f:id:ticktack623:20160125072849p:plain

制限事項

  • Androidでは1つのListViewにつきテンプレート20個まで。
  • DataTemplateSelectorのサブクラスは常に同じデータに対して同じテンプレートを返すこと。
  • DataTemplateSelectorは別のDataTemplateSelectorを返してはならない。
  • DataTemplateSelectorは呼び出し毎に新しいDataTemplateのインスタンスを返してはならない、同じインスタンスを返すこと。さもなくば、結果的に仮想化を無効にし、巨大なメモリリークにつながる。

参考

Xamarin.Forms 2.1.0-pre2 Released - Xamarin Forums