id:tmytさんのアイデアです。
DataTemplateSelectorを実装して、状況に応じてDataTemplateを何個かの中から返すというのはよくやると思います。今回は、これの汎用実装的なかんじです。型名をキーにデータテンプレートを管理するという発想です。
/// <summary> /// DataTemplate保持用クラス /// </summary> [ContentProperty(Name="DataTemplate")] public class DataTemplateHolder { public string TypeName { get; set; } public DataTemplate DataTemplate { get; set; } } /// <summary> /// 型名をキーにDataTemplateを管理して返すDataTemplateSelector /// </summary> [ContentProperty(Name = "Templates")] public class DataTypeDataTemplateSelector : DataTemplateSelector { private List<DataTemplateHolder> templates = new List<DataTemplateHolder>(); /// <summary> /// 型名とDataTemplateのリスト /// </summary> public List<DataTemplateHolder> Templates { get { return this.templates; } } protected override DataTemplate SelectTemplateCore(object item) { if (item == null) { return null; } // 登録してるDataTemplateに、対応する型名のものがあったらそれを返す var r = this.Templates.FirstOrDefault(i => i.TypeName == item.GetType().Name); return r != null ? r.DataTemplate : null; } }
使い方
例えば、こんな2種類のクラスがあったとします。
public class Person { public string Name { get; set; } } public class Dog { public string Name { get; set; } }
ListViewに先ほどのDataTypeDataTemplateSelectorを設定します。
<ListView ItemsSource="{Binding}"> <ListView.ItemTemplateSelector> <local:DataTypeDataTemplateSelector> <local:DataTemplateHolder TypeName="Person"> <DataTemplate> <StackPanel> <TextBlock Text="Personだよ" /> <TextBlock Text="{Binding Name}" /> </StackPanel> </DataTemplate> </local:DataTemplateHolder> <local:DataTemplateHolder TypeName="Dog"> <DataTemplate> <StackPanel> <TextBlock Text="Dogだよ" /> <TextBlock Text="{Binding Name}" /> </StackPanel> </DataTemplate> </local:DataTemplateHolder> </local:DataTypeDataTemplateSelector> </ListView.ItemTemplateSelector> </ListView>
ListViewのItemsSourceにデータを設定するため、ページのコンストラクタに以下のようなコードを書きます。
public MainPage() { this.InitializeComponent(); this.DataContext = Enumerable.Range(1, 100) .Select(i => i % 2 == 0 ? (object)new Person { Name = "にんげん" + i } : (object)new Dog { Name = "ぽち" + i }); }
実行すると、型に応じてテンプレートが切り替わってることが確認できます。
こういうユーテリティ類は懐に用意しておくとよさげですね。