【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, }, } }; }
結果はこのようになります。
制限事項
- Androidでは1つのListViewにつきテンプレート20個まで。
- DataTemplateSelectorのサブクラスは常に同じデータに対して同じテンプレートを返すこと。
- DataTemplateSelectorは別のDataTemplateSelectorを返してはならない。
- DataTemplateSelectorは呼び出し毎に新しいDataTemplateのインスタンスを返してはならない、同じインスタンスを返すこと。さもなくば、結果的に仮想化を無効にし、巨大なメモリリークにつながる。