none
カスタムコントロールで条件により暗黙的なコレクション構文を使用できない RRS feed

  • 質問

  • こんにちは。

    WPFでカスタムコントロールを作っているのですが、以下の事象を発見しました。これはバグでしょうか。それとも仕様でしょうか? MSDNを精読したつもりでしたが、該当するような表現は見つかりませんでした。

    1. コントロールに、コレクション型の読み取り専用のDependencyPropertyを追加します。

            private static readonly DependencyPropertyKey TestCollectionPropertyKey
                = DependencyProperty.RegisterReadOnly(
                    "TestProperty",
                    typeof(TestCollection),
                    typeof(VerticalLinesControl),
                    new PropertyMetadata(default(TestCollection)));
    
            public TestCollection TestProperty {
                get { return (TestCollection) GetValue(TestCollectionPropertyKey.DependencyProperty); }
                private set { SetValue(TestCollectionPropertyKey, value); }
            }

    2. このプロパティに、暗黙的なコレクション構文を用いて要素を追加しようとすると、「TestPropertyにはアクセス可能なsetアクセサーがない」というエラーが出て、ビルドできません。

            <local:MyControl>
                <local:MyControl.TestProperty>
                    <local:TestItemCollectionItem />
                    <local:TestItemCollectionItem />
                </local:MyControl.TestProperty>
            </local:MyControl>

    3. ただし、1.のコードのCLRプロパティのプライベートなsetterを削除すると、ビルドでき普通に使えます。

            private static readonly DependencyPropertyKey TestCollectionPropertyKey
                = DependencyProperty.RegisterReadOnly(
                    "TestProperty",
                    typeof(TestCollection),
                    typeof(VerticalLinesControl),
                    new PropertyMetadata(default(TestCollection)));
    
            public TestCollection TestProperty {
                get { return (TestCollection) GetValue(TestCollectionPropertyKey.DependencyProperty); }
            }

    プライベートなSetterの有無によってパブリックな挙動が変化するというのはどうかと思うのですが、いかがでしょうか。


    • 編集済み terasato 2015年5月22日 8:11
    2015年5月22日 8:09

回答

すべての返信

  • 依存関係プロパティを定義する場合のチェックリストにはsetアクセサーを実装する必要があると記されています。これに従わず実装しない方が悪いかなと。
    2015年5月22日 8:46
  • 返信ありがとうございます。リンクは読み書きできる依存関係プロパティの話ですね。

    読み取り専用の依存関係プロパティによれば、「読み取り専用依存関係プロパティを作成するプロセスのほとんどは、「カスタム依存関係プロパティ」および「方法 : 依存関係プロパティを実装する」の説明と同じです。 ただし、次の 3 つの重要な違いがあります。…・ CLR の "ラッパー" プロパティを実装するときは、ラッパーにも set 実装をしないようにして、公開するパブリック ラッパーの読み取り専用状態が矛盾しないようにする必要があります。」とあります。

    先のコードは「公開する」パブリック ラッパーは読み取り専用で、読み取り専用状態が矛盾していないと考えていたのですがいかがでしょうか。

    2015年5月22日 9:02
  • こんにちは。

    以下が該当しそうですが、如何でしょう。
    (私の英語力では読み取りきれなかったので検討違いだったらすみません…)

    https://connect.microsoft.com/VisualStudio/feedback/details/680380/collection-properties-in-xaml-non-public-set-accessor-vs-no-set-accessor

    ReadOnlyプロパティとPrivateSetterなReadWriteプロパティではそもそも、XAMLパーサの動作が異なるということでしょうか。

    これはバグでしょうか。それとも仕様でしょうか?

    バグなのか仕様なのかいまいちわからないコメントの上でクローズのされていますが…、
    回避策どおりではありますね。

    • 回答の候補に設定 星 睦美 2015年5月25日 4:05
    • 回答としてマーク terasato 2015年5月26日 1:20
    2015年5月22日 15:39
    モデレータ
  • 返信が遅くなりました。

    引用してくださったConnectのスレッドは、まさにこれ! でした。ありがとうございます。

    開発者に引き継がれているようですが、変更はされないんでしょうかね…

    良い勉強になりました。皆さまありがとうございました。

    2015年5月26日 1:21