在 XAML 中初始化没有数组的自定义集合

Initialize custom collection without array in XAML

我正在创建一个自定义控件,其中包含一组要显示的对象。我希望这是一个包装器,上面有一些东西,还有一个内部部分,用于承载由控件的使用者确定的其他东西。基本上我希望它的使用方式类似于 StackPanel,用户可以在 StackPanel 中创建它并在内容部分添加控件。我基本上是在处理一件我想不通的事情。这里是需要设置的'Pages'依赖属性:

    public static readonly DependencyProperty PagesProperty =
        DependencyProperty.Register("Pages", typeof(IEnumerable<MyContentPage>), typeof(UC_ApplicationWindow),
            new PropertyMetadata(new List<MyContentPage>()));

    public IList<MyContentPage> Pages
    {
        get => (IList<MyContentPage>)GetValue(PagesProperty);
        set => SetValue(PagesProperty, value);
    }

这是当前正在运行的此控件的使用者 window 的代码:

        <graphicElements:UC_ApplicationWindow.Pages>
            <x:Array Type="graphicElements:MyContentPage">
                <graphicElements:MyContentPage>
                    <graphicElements:MyContentPage.Content>
                        ...the contents of the page
                    </graphicElements:MyContentPage.Content>
                </graphicElements:MyContentPage>
                <graphicElements:MyContentPage>
                    <graphicElements:MyContentPage.Content>
                        ...the contents of the page
                    </graphicElements:MyContentPage.Content>
                </graphicElements:MyContentPage>
            </x:Array>
        </graphicElements:UC_ApplicationWindow.Pages>

理想情况下,我希望能够为页面 属性 设置多个元素,而不必给它一个数组,但是如果我尝试直接这样做,我会得到错误 'The specified value could not be assigned. The following type was expected: "IList'1".'我也希望能够像大多数其他 WPF 控件一样直接指定页面内容,但是当我取出直接内容 属性 时,它说“类型 'MyContentPage' 不支持直接内容”。这是我最终希望它看起来像的样子:

        <graphicElements:UC_ApplicationWindow.Pages>
            <graphicElements:MyContentPage>
                ...the contents of the page
            </graphicElements:MyContentPage>
            <graphicElements:MyContentPage>
                ...the contents of the page
            </graphicElements:MyContentPage>
        </graphicElements:UC_ApplicationWindow.Pages>

正如我所说,它目前有效,如果这是我必须做的,我可以,但它看起来有点笨拙,我有预感它可以更好地工作,但无法弄清楚如何。谁有我丢失的魔法钥匙?

好的,感谢 this post,我明白了。您需要做的就是将 'ContentProperty' 属性添加到顶部,并且 XAML 将在直接指定时将 属性 解析为内容。所以在这种情况下,我实际上做了两次。我将 [ContentProperty(nameof(Pages))] 放在主应用程序 window class 上,将 [ContentProperty(nameof(Content))] 放在 MyContentPage class.

我也想通了,感谢对 this post 的评论我想通了,如果将页面 属性 设置为 IList 而不是 IEnumerable,则不必直接指定数组,它只是创建它。现在代替这个:

<UC_ApplicationWindow>
    <graphicElements:UC_ApplicationWindow.Pages>
        <x:Array Type="graphicElements:MyContentPage">
            <graphicElements:MyContentPage>
                <graphicElements:MyContentPage.Content>
                    ...the contents of the page
                </graphicElements:MyContentPage.Content>
            </graphicElements:MyContentPage>
            <graphicElements:MyContentPage>
                <graphicElements:MyContentPage.Content>
                    ...the contents of the page
                </graphicElements:MyContentPage.Content>
            </graphicElements:MyContentPage>
        </x:Array>
    </graphicElements:UC_ApplicationWindow.Pages>
</UC_ApplicationWindow>

我可以这样做:

<UC_ApplicationWindow>
    <graphicElements:MyContentPage>
        ...the contents of the page
    </graphicElements:MyContentPage>
    <graphicElements:MyContentPage>
        ...the contents of the page
    </graphicElements:MyContentPage>
</UC_ApplicationWindow>

啊啊啊……干净多了:)