如何在 Xaml 元素中填充多个集合属性
我正在创建一个继承自 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不确定是否可以回答我自己的问题,但是,由于似乎没有人知道,我将分享我采用的解决方案。
显然,Xaml 中对泛型的支持是有限的,这意味着没有本机 Xaml 机制来填充
Dictionary
(或任何其他泛型集合类)。但是,正如本文所述,这是可能的创建自定义标记扩展类,一旦配置为适合集合成员类型,它将成功以声明方式填充集合属性:
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: