如何在 Xaml 元素中填充多个集合属性

发布于 2024-08-28 03:33:23 字数 1719 浏览 5 评论 0原文

我正在创建一个继承自 System.Windows.Documents.Paragraph 的类并添加一个新的集合属性。下面是该类的非常简化的表示:

public class ExtendedParagraph : Paragraph
{
    public Dictionary<string, string> Attributes { get; set; }
}

我需要从 Xaml 中创建并填充上述类的实例,这需要一种标记语法,允许单独声明段落的内容及其 Attributes 集合的成员。

由于 Paragraph 类使用属性 [ContentProperty("Inlines")] 进行装饰,因此我假设需要显式填充 Inlines 和 Attributes 集合。基于我在其他地方看到的用于解决类似挑战的 Xaml 语法,我设想了这样的事情:

<ExtendedParagraph xmlns="clr-namespace:MyNamespace">
    <ExtendedParagraph.Inlines>

        This is where the paragraph content goes

    </ExtendedParagraph.Inlines>
    <ExtendedParagraph.Attributes>

        This is where the members of the Attributes property are declared 

    </ExtendedParagraph.Attributes>
</ExtendedParagraph>

但是,这种方法存在两个问题:

[1] 当使用 XamlReader 解析上述 Xaml 时,它会失败并显示消息“ExtendedParagraph.Inlines”属性已被设置,并且只能设置一次”

[2] 我不确定应该使用什么标记来声明 Attributes 元素中的 KeyValuePair 实例。

我希望有人能指出我正确的方向。

非常感谢, 蒂姆

编辑 - 我找到了问题 [1] 的答案。它只需要首先声明 Attributes 集合(使用属性元素语法),然后声明段落的内容:

<ExtendedParagraph xmlns="clr-namespace:MyNamespace">
    <ExtendedParagraph.Attributes>

        This is where the members of the Attributes property are declared 

    </ExtendedParagraph.Attributes>
    This is where the paragraph content goes
</ExtendedParagraph>

但是,以声明方式将成员添加到 Dictionary 被证明更加困难。我在 这篇文章,但我还没有取得工作结果。仍然欢迎您的想法。

I am creating a class that inherits from System.Windows.Documents.Paragraph and adds a new collection property. Here is a very simplified representation of that class:

public class ExtendedParagraph : Paragraph
{
    public Dictionary<string, string> Attributes { get; set; }
}

I need to create and populate an instance of the above class from within Xaml, which requires a markup syntax that allows the content of the paragraph and the members of its Attributes collection to be declared separately.

Since the Paragraph class is decorated with the attribute [ContentProperty("Inlines")], I assume I need to explicitly populate the Inlines and the Attributes collections. Based on the Xaml syntax I have seen used to solve similar challenges elsewhere, I envisage something like this:

<ExtendedParagraph xmlns="clr-namespace:MyNamespace">
    <ExtendedParagraph.Inlines>

        This is where the paragraph content goes

    </ExtendedParagraph.Inlines>
    <ExtendedParagraph.Attributes>

        This is where the members of the Attributes property are declared 

    </ExtendedParagraph.Attributes>
</ExtendedParagraph>

However, this approach presents two problems:

[1] When the above Xaml is parsed using XamlReader, it fails with the message "ExtendedParagraph.Inlines property has already been set and can only be set once"

[2] I am not sure what markup I should use to declare instances of KeyValuePair within the Attributes element.

I hope somebody can point me in the right direction.

Many thanks,
Tim

Edit - I have found the answer to question [1]. It simply entails declaring the Attributes collection (using property element syntax) first, followed by the content of the Paragraph:

<ExtendedParagraph xmlns="clr-namespace:MyNamespace">
    <ExtendedParagraph.Attributes>

        This is where the members of the Attributes property are declared 

    </ExtendedParagraph.Attributes>
    This is where the paragraph content goes
</ExtendedParagraph>

However, declaratively adding members to a Dictionary<TKey, TValue> is proving more difficult. I found a few clues in this post, but I haven't yet achieved a working result. Your ideas are still welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

留蓝 2024-09-04 03:33:23

我不确定是否可以回答我自己的问题,但是,由于似乎没有人知道,我将分享我采用的解决方案。

显然,Xaml 中对泛型的支持是有限的,这意味着没有本机 Xaml 机制来填充 Dictionary (或任何其他泛型集合类)。

但是,正如本文所述,这是可能的创建自定义标记扩展类,一旦配置为适合集合成员类型,它将成功以声明方式填充集合属性:

<ExtendedParagraph.Attributes>
    <generic:DictionaryOfT TypeArgument="sys:String">
        <generic:DictionaryOfT.Items>
            <sys:String x:Key="String1">Hello</sys:String>
            <sys:String x:Key="String2">World</sys:String>
        </generic:DictionaryOfT.Items>
    </generic:DictionaryOfT>
</ExtendedParagraph.Attributes>

I'm not sure whether it's OK to answer my own question but, since nobody else seems to know, I'll share the solution I have adopted.

Apparently, support for generics in Xaml is limited, which means there is no native Xaml machamism to populate a Dictionary<TKey, TValue> (or any other generic collection class).

However, as this article describes, it is possible to create a custom markup extension class and, once configured to suit the collection member type, it will successfully populate a collection property declaratively:

<ExtendedParagraph.Attributes>
    <generic:DictionaryOfT TypeArgument="sys:String">
        <generic:DictionaryOfT.Items>
            <sys:String x:Key="String1">Hello</sys:String>
            <sys:String x:Key="String2">World</sys:String>
        </generic:DictionaryOfT.Items>
    </generic:DictionaryOfT>
</ExtendedParagraph.Attributes>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文