id:tmytさんのアイデアです。
DataTemplateSelectorを実装して、状況に応じてDataTemplateを何個かの中から返すというのはよくやると思います。今回は、これの汎用実装的なかんじです。型名をキーにデータテンプレートを管理するという発想です。
/// <summary>/// DataTemplate保持用クラス/// </summary> [ContentProperty(Name="DataTemplate")] publicclass DataTemplateHolder { publicstring TypeName { get; set; } public DataTemplate DataTemplate { get; set; } } /// <summary>/// 型名をキーにDataTemplateを管理して返すDataTemplateSelector/// </summary> [ContentProperty(Name = "Templates")] publicclass DataTypeDataTemplateSelector : DataTemplateSelector { private List<DataTemplateHolder> templates = new List<DataTemplateHolder>(); /// <summary>/// 型名とDataTemplateのリスト/// </summary>public List<DataTemplateHolder> Templates { get { returnthis.templates; } } protectedoverride DataTemplate SelectTemplateCore(object item) { if (item == null) { returnnull; } // 登録してるDataTemplateに、対応する型名のものがあったらそれを返す var r = this.Templates.FirstOrDefault(i => i.TypeName == item.GetType().Name); return r != null ? r.DataTemplate : null; } }
使い方
例えば、こんな2種類のクラスがあったとします。
publicclass Person { publicstring Name { get; set; } } publicclass Dog { publicstring 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 }); }
実行すると、型に応じてテンプレートが切り替わってることが確認できます。
こういうユーテリティ類は懐に用意しておくとよさげですね。