ContentPropertyAttribute

Buttonのようなコンテンツを指定できるタグはどうやってできるのか。
また、コレクションに関するXAMLの書き方についても扱う。

XAML側
XAML

XAML側をこう書いただけでは、TestClassがないので当然こうなる。
TestClass.csに、

// 名前空間
namespace BGST
{

    // テストクラス
    public class TestClass  // TestClassの定義
    {

        // 普通の文字列プロパティ.
        private string testProperty;    // string型のフィールドtestProperty.
        public string TestProperty
        {
            // 取得
            get
            {
                return testProperty;    // testPropertyを返す.
            }
            // 設定
            set
            {
                testProperty = value;   // testPropertyに代入.
            }
        }

    }
}

TestClassを定義することで、

認識はする
認識はする

認識はする。
ただし、プロパティはタグ内の属性でしか指定できない。
さて、

// 名前空間の登録
using System.Collections.ObjectModel;   // コレクションオブジェクトモデルクラス(System.Collections.ObjectModel名前空間)

// 名前空間
namespace BGST
{

    // テストクラス
    public class TestClass  // TestClassの定義
    {

        // 普通の文字列プロパティ.
        private string testProperty;    // string型のフィールドtestProperty.
        public string TestProperty
        {
            // 取得
            get
            {
                return testProperty;    // testPropertyを返す.
            }
            // 設定
            set
            {
                testProperty = value;   // testPropertyに代入.
            }
        }

        // 自身のコレクションのプロパティ.
        public Collection<TestClass> TestCollection
        {
            get;
            set;
        }

    }

}

自身のコレクションを持つプロパティTestCollectionを定義する。
すると、

TestCollectionサブタグの下に自身のタグ
TestCollectionサブタグの下に自身のタグ

TestCollectionサブタグの下に自身のタグを入れ子出来る。

ビルドは通る
ビルドは通る

ビルドは通る。

例外
例外

しかし、例外になってしまう。

// 名前空間の登録
using System.Collections.ObjectModel;   // コレクションオブジェクトモデルクラス(System.Collections.ObjectModel名前空間)

// 名前空間
namespace BGST
{

    // テストクラス
    public class TestClass  // TestClassの定義
    {

        // コンストラクタ
        public TestClass()
        {
            // コレクションの初期化.
            TestCollection = new Collection<TestClass>();   // TestCollectionを生成しておかないといけない.
        }

        // 普通の文字列プロパティ.
        private string testProperty;    // string型のフィールドtestProperty.
        public string TestProperty
        {
            // 取得
            get
            {
                return testProperty;    // testPropertyを返す.
            }
            // 設定
            set
            {
                testProperty = value;   // testPropertyに代入.
            }
        }

        // 自身のコレクションのプロパティ.
        public Collection<TestClass> TestCollection
        {
            get;
            set;
        }

    }

}

どうもTestCollectionにインスタンスがないのが原因のようなので、コンストラクタで生成するようにした。

動いたけどわからない
動いたけどわからない

動いたけど何もわからない。
さて、TestClassCollection.csを追加し、

Collection<TestClass>を別クラスのTestClassCollectionとした。

そして、

// 名前空間の登録
using System.Collections.ObjectModel;   // コレクションオブジェクトモデルクラス(System.Collections.ObjectModel名前空間)
using System.Windows.Markup;    // マークアップ(System.Windows.Markup名前空間)

// 名前空間
namespace BGST
{

    // テストクラス
    public class TestClass  // TestClassの定義
    {

        // コンストラクタ
        public TestClass()
        {
            // コレクションの初期化.
            TestCollection = new TestClassCollection(); // TestClassCollectionを生成.
        }

        // 普通の文字列プロパティ.
        private string testProperty;    // string型のフィールドtestProperty.
        public string TestProperty
        {
            // 取得
            get
            {
                return testProperty;    // testPropertyを返す.
            }
            // 設定
            set
            {
                testProperty = value;   // testPropertyに代入.
            }
        }

        // 自身のコレクションのプロパティ.
        public TestClassCollection TestCollection
        {
            get;
            set;
        }

    }

}

として、

TestClassCollectionタグ
TestClassCollectionタグ

サブタグの下にコレクション、コレクションの下にアイテムという形にできた。

これでも動いた
これでも動いた

これでも動いた。

コレクションクラスは省略できる
コレクションクラスは省略できる

しかし、実はコレクションクラスはなくても、

動く
動く

動く。
これがコレクション構文。

WPF4.5入門 その9 「コレクション構文」 - かずきのBlog@hatena

さらに、

ContentProperty属性で指定したプロパティは、ButtonのContentのように中に直接書くことができる。

ContentPropertyAttribute Class (System.Windows.Markup) | Microsoft Docs

なので、

サブタグも省略
サブタグも省略

サブタグも省略できる。
これがコンテンツ構文。

WPF4.5入門 その10 「コンテンツ構文」 - かずきのBlog@hatena

これでTestClassタグを入れ子できることがわかる。

見た目は変わらない
見た目は変わらない

見た目は変わらないようだが・・・。

Sample/wpf/ContentPropertyAttribute/ContentPropertyAttribute/src/ContentPropertyAttribute_ at master · bg1bgst333/Sample · GitHub