在依赖对象上的XAML中启用直接内容创建

Ant*_*nes 4 c# silverlight xaml dependencyobject silverlight-3.0

我上课了CollectionOfThings.顾名思义,它是一个简单的Thing类实例集合. Thing类有一个公共的默认构造函数和两个简单的公众获取,设置属性IDDisplayName,两者都是字符串. 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>
Run Code Online (Sandbox Code Playgroud)

只要CollectionOfThings派生自Collection类型,一切都很好.但是我想CollectionOfThings也是一个DependencyObject.我认为这很好创造的实现ICollection<T>,INotifyCollectionChanged等等并不难.然后我可以从中衍生出来DependencyObject.

不幸的是ICollection<T>,由于某种原因不会削减它.随着ICollection<Thing>我得到'CollectionOfThings不支持Thing作为内容'.回去Collection<Thing>,一切正常,但没有DependencyObject实现让我离开.

有人建议吗?

Pav*_*aev 7

XAML希望System.Collections.IList(非通用的!)用于集合.如果你只实现通用IList<T>接口,它不会削减它.

它还希望Add在类上看到公共方法,并从这些方法的参数中为集合派生合适的子类型.因此,典型的方法是显式实现IList- 因此它的Add(object)方法不是公共的,因此不被XAML解析器选择 - 然后隐式实现IList<T>您想要支持的所有子类型.

为什么它适用于大多数内置集合类型(的原因List<T>,Collection<T>等等)是因为他们遵循上述模式,同时实现通用和非通用接口.


Ken*_* K. 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; } 
}
Run Code Online (Sandbox Code Playgroud)

然而,如果类不提供为一个值ContentPropertyAttribute,并实现类型的任何接口IList<T>,IList,ICollection<T>ICollection,的名称为"文件"的属性(如果存在的话,并且如果适当的类型,例如IList)被自动检测槽反射(对人口的目的是通过xaml),这就是Collection<T>班级的情况.

您甚至可以在Reflector中检查该类,以确保它没有定义内容属性.

这个Collection<T>类有这个属性

protected IList<T> Items
{
    get
    {
        return _items;
    }
}
Run Code Online (Sandbox Code Playgroud)

并在您的集合类型中添加类似的东西(即使属性受到保护)足以让它在xaml中按照需要运行.

我想这种行为是以这种方式实现的,以实现向后兼容.