我有一个班级CollectionOfThings
。正如其名称所示,它是Thing
类的简单实例集合。 Thing
类有一个公共默认构造函数和两个简单的公共get,set属性ID
和DisplayName
,两者都是字符串。 CollectionOfThing
也有公共默认构造函数。
在XAML中,我想使用这样的标记: -
<Grid.Resources>
<local:CollectionOfThings x:Key="Things">
<local:Thing ID="1" DisplayName="Hello" />
<local:Thing ID="2" DisplayName="World" />
<local:CollectionOfThings>
</Grid.Resources>
只要CollectionOfThings派生自Collection类型,一切都很好。不过,我希望CollectionOfThings
也是DependencyObject
。我认为创建ICollection<T>
,INotifyCollectionChanged
等实现并不是那么难。然后我可以从DependencyObject
派生。
不幸的是ICollection<T>
因某些原因没有删除它。使用ICollection<Thing>
我得到'CollectionOfThings不支持Thing as content'。回到Collection<Thing>
,一切正常,但没有DependencyObject
实施。
建议任何人?
答案 0 :(得分:7)
XAML希望System.Collections.IList
(非通用的!)用于集合。如果您只实现通用IList<T>
接口,则不会删除它。
它还希望在类上看到公共Add
方法,并从这些方法的参数中为集合派生合适的子类型。因此,典型的方法是显式实现IList
- 以使其Add(object)
方法不公开,因此不被XAML解析器选中 - 然后为所有子项隐式实现IList<T>
您想要支持的类型。
它适用于大多数内置集合类型(List<T>
,Collection<T>
等)的原因是因为它们遵循上述模式并实现了通用和非通用接口。
答案 1 :(得分:5)
通常在xaml中使用集合,以便在ContentPropertyAttribute("PropertyName")
通常为PropertyName
或IList
的自定义类中定义IList<T>
。
[ContentProperty(SomeProp)]
class SomeClass
{
//this is where subitems created in xaml would get added automatically
public IList<int> SomeProp { get; set; }
}
但是,如果某个类没有为ContentPropertyAttribute
提供值,并且实现了IList<T>
,IList
,ICollection<T>
或ICollection
类型的任何接口,名称为“Items”的属性(如果存在,如果是适当的类型,例如IList
)通过自动反射检测(为了人口通过xaml的目的),{{1 }。class。
您甚至可以在Reflector中检查类,以确保它没有定义内容属性。
Collection<T>
类具有此属性
Collection<T>
并将类似内容添加到您的集合类型中(即使属性受到保护)足以让它在xaml中按照需要运行。
我认为这种行为是以这种方式实现的,以实现向后兼容。