4

我有一堂课CollectionOfThings。顾名思义,它是Thing类实例的简单集合。 Thing类有一个公共的默认构造函数和两个简单​​的公共 get、set 属性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>

只要 CollectionOfThings 派生自 Collection 类型,一切都很好。不过我CollectionOfThings也想成为一个DependencyObject。我认为创建ICollection<T>, INotifyCollectionChangedetc 的实现很好,这并不难。然后我可以从DependencyObject.

不幸的是ICollection<T>,由于某种原因没有削减它。随着ICollection<Thing>我得到“CollectionOfThings 不支持将事物作为内容”。回去Collection<Thing>,一切正常,但让我没有DependencyObject实施。

建议任何人?

4

2 回答 2

7

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

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

它适用于大多数内置集合类型(List<T>Collection<T>)的原因是它们遵循上述模式并实现通用和非通用接口。

于 2009-07-08T21:18:09.567 回答
5

集合通常在 xaml 中使用,以便在通常为或ContentPropertyAttribute("PropertyName")的自定义类上定义 a 。PropertyNameIListIList<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,则通过反射自动检测到名为“Items”的属性(如果存在,并且如果具有适当的类型,例如)(对于通过 xaml 填充的目的),这就是类的情况。ICollection<T>ICollectionIListCollection<T>

您甚至可以检查 Reflector 中的类以确保它没有定义内容属性。

该类Collection<T>具有此属性

protected IList<T> Items
{
    get
    {
        return _items;
    }
}

并将类似的内容添加到您的集合类型(即使该属性受到保护)就足以让它在 xaml 中按预期运行。

我想这种行为是为了向后兼容而实现的。

于 2009-07-08T20:38:58.600 回答