かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

WPF4.5入門 その9 「コレクション構文」

コレクション構文

XAMLでは、コレクションのプロパティを簡単に記述するためのコレクション構文が用意されています。具体的には、コレクションのプロパティを設定する際に、コレクション型を明に指定せずに、コレクションの要素を複数指定します。具体例を以下に示します。
コレクション型のプロパティのChildrenプロパティを持ったItemという型を定義します。

namespace CollectionXaml
{
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
 
    public class Item
    {
        public Item()
        {
            this.Children = new ItemCollection();
        }
 
        public string Id { get; set; }
        // コレクション型のプロパティ
        public ItemCollection Children { get; set; }
    }
 
    public class ItemCollection : Collection<Item> { }
}

Childrenプロパティに要素を3つ設定したXAMLは以下のようになります。

<Item xmlns="clr-namespace:CollectionXaml;assembly=CollectionXaml"
      Id="item1">
    <Item.Children>
        <!--<ItemCollection>-->
            <Item Id="item1-1" />
            <Item Id="item1-2" />
            <Item Id="item1-3" />
        <!--</ItemCollection>-->
    </Item.Children>
</Item>

ここでコメントアウトしているように<Item.Children>〜</Item.Children>の設定の箇所で<ItemCollection>の設定を省略できる点がコレクション構文の優れたところです。このように省略すると、XAMLをパースする段階で自動的にChildrenプロパティからコレクションが取得されItemが追加されます。明示的にタグを使ってコレクションを設定しても、XAMLをパースして得られるものは同じですが、この場合はChildrenプロパティの書き込みが許可されていなければいけません。
このXAMLを読み込んでItemの内容を表示するプログラムを以下に示します。

namespace CollectionXaml
{
    using System;
    using System.Windows.Markup;
 
    class Program
    {
        static void Main(string[] args)
        {
            var s = typeof(Program).Assembly.GetManifestResourceStream("CollectionXaml.Item.xaml");
            var item = XamlReader.Load(s) as Item;
 
            // Itemの内容を表示
            Console.WriteLine(item.Id);
            foreach (var i in item.Children)
            {
                Console.WriteLine("  {0}", i.Id);
            }
        }
    }
}

このコードを実行すると以下のように表示されます。

item1
  item1-1
  item1-2
  item1-3

コレクション構文によって、設定した項目が取得できていることが確認できます。