Quantcast
Channel: かずきのBlog@hatena
Viewing all articles
Browse latest Browse all 1387

Windows RuntimeのXAMLで、型に応じてDataTemplateを選択したい

$
0
0

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 });
}

実行すると、型に応じてテンプレートが切り替わってることが確認できます。

f:id:okazuki:20140706182946j:plain

こういうユーテリティ類は懐に用意しておくとよさげですね。


Viewing all articles
Browse latest Browse all 1387

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>